Skip to content

Commit

Permalink
Merge pull request quarkusio#41993 from aureamunoz/issue-41987
Browse files Browse the repository at this point in the history
Support Spring Data JpaRepository#getReferenceById(ID)
  • Loading branch information
geoand authored Jul 19, 2024
2 parents e61eed4 + 4e06bfb commit 8246009
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ public void add(ClassCreator classCreator, FieldDescriptor entityClassFieldDescr
allMethodsToBeImplementedToResult);
generateGetOne(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr, idTypeStr,
allMethodsToBeImplementedToResult);
generateGetReferenceById(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr, idTypeStr,
allMethodsToBeImplementedToResult);
generateGetById(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr, idTypeStr,
allMethodsToBeImplementedToResult);
generateFindAll(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr,
allMethodsToBeImplementedToResult);
generateFindAllWithSort(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr,
Expand All @@ -115,6 +119,12 @@ public void add(ClassCreator classCreator, FieldDescriptor entityClassFieldDescr
generateDeleteAll(classCreator, entityClassFieldDescriptor, generatedClassName, allMethodsToBeImplementedToResult);
generateDeleteAllInBatch(classCreator, entityClassFieldDescriptor, generatedClassName,
allMethodsToBeImplementedToResult);
generateDeleteAllInBatchWithIterable(classCreator, generatedClassName, entityTypeStr,
allMethodsToBeImplementedToResult);
generateDeleteInBatchWithIterable(classCreator, generatedClassName, entityTypeStr,
allMethodsToBeImplementedToResult);
generateDeleteAllByIdInBatchWithIterable(classCreator, generatedClassName, entityTypeStr,
allMethodsToBeImplementedToResult);

handleUnimplementedMethods(classCreator, allMethodsToBeImplementedToResult);
}
Expand Down Expand Up @@ -508,39 +518,62 @@ private void generateExistsById(ClassCreator classCreator, FieldDescriptor entit
private void generateGetOne(ClassCreator classCreator, FieldDescriptor entityClassFieldDescriptor,
String generatedClassName, String entityTypeStr, String idTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
generateSpecificFindEntityReference(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr,
idTypeStr, "getOne", allMethodsToBeImplementedToResult);

}

private void generateGetById(ClassCreator classCreator, FieldDescriptor entityClassFieldDescriptor,
String generatedClassName, String entityTypeStr, String idTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {

MethodDescriptor getOneDescriptor = MethodDescriptor.ofMethod(generatedClassName, "getOne",
generateSpecificFindEntityReference(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr,
idTypeStr, "getById", allMethodsToBeImplementedToResult);
}

private void generateGetReferenceById(ClassCreator classCreator, FieldDescriptor entityClassFieldDescriptor,
String generatedClassName, String entityTypeStr, String idTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {

generateSpecificFindEntityReference(classCreator, entityClassFieldDescriptor, generatedClassName, entityTypeStr,
idTypeStr, "getReferenceById", allMethodsToBeImplementedToResult);
}

private void generateSpecificFindEntityReference(ClassCreator classCreator, FieldDescriptor entityClassFieldDescriptor,
String generatedClassName, String entityTypeStr, String idTypeStr, String actualMethodName,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
MethodDescriptor getReferenceByIdDescriptor = MethodDescriptor.ofMethod(generatedClassName, actualMethodName,
entityTypeStr, idTypeStr);
MethodDescriptor bridgeGetOneDescriptor = MethodDescriptor.ofMethod(generatedClassName, "getOne",
MethodDescriptor bridgegetReferenceByIdDescriptor = MethodDescriptor.ofMethod(generatedClassName, actualMethodName,
Object.class, Object.class);

if (allMethodsToBeImplementedToResult.containsKey(getOneDescriptor)
|| allMethodsToBeImplementedToResult.containsKey(bridgeGetOneDescriptor)) {
if (allMethodsToBeImplementedToResult.containsKey(getReferenceByIdDescriptor)
|| allMethodsToBeImplementedToResult.containsKey(bridgegetReferenceByIdDescriptor)) {

if (!classCreator.getExistingMethods().contains(getOneDescriptor)) {
try (MethodCreator findById = classCreator.getMethodCreator(getOneDescriptor)) {
if (!classCreator.getExistingMethods().contains(getReferenceByIdDescriptor)) {
try (MethodCreator findById = classCreator.getMethodCreator(getReferenceByIdDescriptor)) {

ResultHandle entity = findById.invokeStaticMethod(ofMethod(RepositorySupport.class, "getOne",
ResultHandle entity = findById.invokeStaticMethod(ofMethod(RepositorySupport.class, actualMethodName,
Object.class, AbstractJpaOperations.class, Class.class, Object.class),
findById.readStaticField(operationsField),
findById.readInstanceField(entityClassFieldDescriptor, findById.getThis()),
findById.getMethodParam(0));

findById.returnValue(entity);
}
try (MethodCreator bridgeGetOne = classCreator.getMethodCreator(bridgeGetOneDescriptor)) {
MethodDescriptor getOne = MethodDescriptor.ofMethod(generatedClassName, "getOne",
try (MethodCreator bridgeGetOne = classCreator.getMethodCreator(bridgegetReferenceByIdDescriptor)) {
MethodDescriptor getReferenceById = MethodDescriptor.ofMethod(generatedClassName, actualMethodName,
entityTypeStr, idTypeStr);
ResultHandle methodParam = bridgeGetOne.getMethodParam(0);
ResultHandle castedMethodParam = bridgeGetOne.checkCast(methodParam, idTypeStr);
ResultHandle result = bridgeGetOne.invokeVirtualMethod(getOne, bridgeGetOne.getThis(),
ResultHandle result = bridgeGetOne.invokeVirtualMethod(getReferenceById, bridgeGetOne.getThis(),
castedMethodParam);
bridgeGetOne.returnValue(result);
}
}

allMethodsToBeImplementedToResult.put(getOneDescriptor, true);
allMethodsToBeImplementedToResult.put(bridgeGetOneDescriptor, true);
allMethodsToBeImplementedToResult.put(getReferenceByIdDescriptor, true);
allMethodsToBeImplementedToResult.put(bridgegetReferenceByIdDescriptor, true);
}
}

Expand Down Expand Up @@ -886,10 +919,41 @@ private void generateDelete(ClassCreator classCreator, String generatedClassName
allMethodsToBeImplementedToResult.put(bridgeDeleteDescriptor, true);
}

private void generateDeleteInBatchWithIterable(ClassCreator classCreator, String generatedClassName, String entityTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
generateSpecificDeleteAllWithIterable(classCreator, generatedClassName, entityTypeStr, "deleteInBatch",
allMethodsToBeImplementedToResult);

}

private void generateDeleteAllInBatchWithIterable(ClassCreator classCreator, String generatedClassName,
String entityTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
generateSpecificDeleteAllWithIterable(classCreator, generatedClassName, entityTypeStr, "deleteAllInBatch",
allMethodsToBeImplementedToResult);

}

private void generateDeleteAllByIdInBatchWithIterable(ClassCreator classCreator, String generatedClassName,
String entityTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
generateSpecificDeleteAllWithIterable(classCreator, generatedClassName, entityTypeStr, "deleteAllByIdInBatch",
allMethodsToBeImplementedToResult);

}

private void generateDeleteAllWithIterable(ClassCreator classCreator, String generatedClassName, String entityTypeStr,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {
generateSpecificDeleteAllWithIterable(classCreator, generatedClassName, entityTypeStr, "deleteAll",
allMethodsToBeImplementedToResult);

}

private void generateSpecificDeleteAllWithIterable(ClassCreator classCreator, String generatedClassName,
String entityTypeStr, String actualMethodName,
Map<MethodDescriptor, Boolean> allMethodsToBeImplementedToResult) {

MethodDescriptor deleteAllWithIterableDescriptor = MethodDescriptor.ofMethod(generatedClassName, "deleteAll",
MethodDescriptor deleteAllWithIterableDescriptor = MethodDescriptor.ofMethod(generatedClassName, actualMethodName,
void.class, Iterable.class);

if (allMethodsToBeImplementedToResult.containsKey(deleteAllWithIterableDescriptor)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
Expand All @@ -21,6 +22,7 @@
import org.hibernate.Hibernate;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -148,6 +150,58 @@ public void testListOrderByNullHandling() throws MalformedURLException {
assertEquals(uuidForTheNullUrlRecord, list.get(list.size() - 1).getUuid());
}

@Test
@Order(9)
@Transactional
public void testGetReferenceById() throws Exception {
populateData(new BasicTypeData());
assertThat(repo.getReferenceById(1)).isNotNull();
}

@Test
@Order(10)
@Transactional
public void testGetOne() throws Exception {
populateData(new BasicTypeData());
assertThat(repo.getOne(1)).isNotNull();
}

@Test
@Order(11)
@Transactional
public void testGetById() throws Exception {
populateData(new BasicTypeData());
assertThat(repo.getReferenceById(1)).isNotNull();
}

@Test
@Order(12)
@Transactional
public void testDeleteAllInBatch() throws Exception {
Assertions.assertDoesNotThrow(() -> repo.deleteAllInBatch());
}

@Test
@Order(13)
@Transactional
public void testDeleteAllInBatchWithIterable() throws Exception {
Assertions.assertDoesNotThrow(() -> repo.deleteAllInBatch(new ArrayList<>()));
}

@Test
@Order(14)
@Transactional
public void testDeleteInBatch() throws Exception {
Assertions.assertDoesNotThrow(() -> repo.deleteInBatch(new ArrayList<>()));
}

@Test
@Order(15)
@Transactional
public void testDeleteAllByIdInBatch() throws Exception {
Assertions.assertDoesNotThrow(() -> repo.deleteAllByIdInBatch(new ArrayList<>()));
}

private BasicTypeData populateData(BasicTypeData basicTypeData) throws MalformedURLException {
basicTypeData.setDoubleValue(Math.PI);
basicTypeData.setBigDecimalValue(BigDecimal.valueOf(Math.PI * 2.0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,37 @@ public static void deleteAll(AbstractJpaOperations<PanacheQuery<?>> operations,
}
}

/**
* Add call to the Panache method implementing the actual retrieving of a reference to an entity with the given class and
* identifier.
*
* @param operations an instance of {@code AbstractJpaOperations} used to perform JPA operations
* @param entityClass the {@code Class} object of the entity type to be retrieved
* @param id the identifier of the entity to be retrieved
* @return a reference to the entity of the specified class with the given identifier
* @deprecated use {@link RepositorySupport#getReferenceById)} instead.
*/
@Deprecated
public static Object getOne(AbstractJpaOperations<PanacheQuery<?>> operations, Class<?> entityClass, Object id) {
return getReferenceById(operations, entityClass, id);
}

/**
* Add call to the Panache method implementing the actual retrieving of a reference to an entity with the given class and
* identifier.
*
* @param operations an instance of {@code AbstractJpaOperations} used to perform JPA operations
* @param entityClass the {@code Class} object of the entity type to be retrieved
* @param id the identifier of the entity to be retrieved
* @return a reference to the entity of the specified class with the given identifier
* @deprecated use {@link RepositorySupport#getReferenceById)} instead.
*/
@Deprecated
public static Object getById(AbstractJpaOperations<PanacheQuery<?>> operations, Class<?> entityClass, Object id) {
return getReferenceById(operations, entityClass, id);
}

public static Object getReferenceById(AbstractJpaOperations<PanacheQuery<?>> operations, Class<?> entityClass, Object id) {
return operations.getSession(entityClass).getReference(entityClass, id);
}

Expand Down

0 comments on commit 8246009

Please sign in to comment.