Polishing.
Simplify code flow. Introduce flag to capture whether a stored procedure uses collection return types. Remove unconditionally the Optional converter as we're already on Java 17 and do not require the Java 8 guard. See #2915 Original pull request: #2938
This commit is contained in:
@@ -92,7 +92,7 @@ public abstract class AbstractJpaQuery implements RepositoryQuery {
|
||||
if (method.isStreamQuery()) {
|
||||
return new StreamExecution();
|
||||
} else if (method.isProcedureQuery()) {
|
||||
return new ProcedureExecution();
|
||||
return new ProcedureExecution(method.isCollectionQuery());
|
||||
} else if (method.isCollectionQuery()) {
|
||||
return new CollectionExecution();
|
||||
} else if (method.isSliceQuery()) {
|
||||
|
||||
@@ -66,7 +66,7 @@ public abstract class JpaQueryExecution {
|
||||
|
||||
conversionService.addConverter(JpaResultConverters.BlobToByteArrayConverter.INSTANCE);
|
||||
conversionService.removeConvertible(Collection.class, Object.class);
|
||||
potentiallyRemoveOptionalConverter(conversionService);
|
||||
conversionService.removeConvertible(Object.class, Optional.class);
|
||||
|
||||
CONVERSION_SERVICE = conversionService;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ public abstract class JpaQueryExecution {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doExecute(final AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
|
||||
protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
|
||||
|
||||
Query query = repositoryQuery.createQuery(accessor);
|
||||
|
||||
@@ -294,20 +294,25 @@ public abstract class JpaQueryExecution {
|
||||
*/
|
||||
static class ProcedureExecution extends JpaQueryExecution {
|
||||
|
||||
private final boolean collectionQuery;
|
||||
|
||||
private static final String NO_SURROUNDING_TRANSACTION = "You're trying to execute a @Procedure method without a surrounding transaction that keeps the connection open so that the ResultSet can actually be consumed; Make sure the consumer code uses @Transactional or any other way of declaring a (read-only) transaction";
|
||||
|
||||
ProcedureExecution(boolean collectionQuery) {
|
||||
this.collectionQuery = collectionQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAccessor accessor) {
|
||||
|
||||
Assert.isInstanceOf(StoredProcedureJpaQuery.class, jpaQuery);
|
||||
|
||||
StoredProcedureJpaQuery storedProcedureJpaQuery = (StoredProcedureJpaQuery) jpaQuery;
|
||||
|
||||
StoredProcedureQuery storedProcedure = storedProcedureJpaQuery.createQuery(accessor);
|
||||
StoredProcedureJpaQuery query = (StoredProcedureJpaQuery) jpaQuery;
|
||||
StoredProcedureQuery procedure = query.createQuery(accessor);
|
||||
|
||||
try {
|
||||
|
||||
boolean returnsResultSet = storedProcedure.execute();
|
||||
boolean returnsResultSet = procedure.execute();
|
||||
|
||||
if (returnsResultSet) {
|
||||
|
||||
@@ -315,20 +320,15 @@ public abstract class JpaQueryExecution {
|
||||
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
|
||||
}
|
||||
|
||||
if (storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) {
|
||||
return storedProcedure.getResultList();
|
||||
} else {
|
||||
return storedProcedure.getSingleResult();
|
||||
}
|
||||
return collectionQuery ? procedure.getResultList() : procedure.getSingleResult();
|
||||
}
|
||||
|
||||
return storedProcedureJpaQuery.extractOutputValue(storedProcedure);
|
||||
|
||||
return query.extractOutputValue(procedure);
|
||||
} finally {
|
||||
|
||||
if (storedProcedure instanceof AutoCloseable autoCloseable) {
|
||||
if (procedure instanceof AutoCloseable ac) {
|
||||
try {
|
||||
autoCloseable.close();
|
||||
ac.close();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
@@ -345,10 +345,10 @@ public abstract class JpaQueryExecution {
|
||||
|
||||
private static final String NO_SURROUNDING_TRANSACTION = "You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed; Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction";
|
||||
|
||||
private static Method streamMethod = ReflectionUtils.findMethod(Query.class, "getResultStream");
|
||||
private static final Method streamMethod = ReflectionUtils.findMethod(Query.class, "getResultStream");
|
||||
|
||||
@Override
|
||||
protected Object doExecute(final AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
|
||||
protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
|
||||
|
||||
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) {
|
||||
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
|
||||
@@ -369,24 +369,4 @@ public abstract class JpaQueryExecution {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the converter being able to convert any object into an {@link Optional} from the given
|
||||
* {@link ConversionService} in case we're running on Java 8.
|
||||
*
|
||||
* @param conversionService must not be {@literal null}.
|
||||
*/
|
||||
public static void potentiallyRemoveOptionalConverter(ConfigurableConversionService conversionService) {
|
||||
|
||||
ClassLoader classLoader = JpaQueryExecution.class.getClassLoader();
|
||||
|
||||
if (ClassUtils.isPresent("java.util.Optional", classLoader)) {
|
||||
|
||||
try {
|
||||
|
||||
Class<?> optionalType = ClassUtils.forName("java.util.Optional", classLoader);
|
||||
conversionService.removeConvertible(Object.class, optionalType);
|
||||
|
||||
} catch (ClassNotFoundException | LinkageError o_O) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ class JpaRepositoryTests {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
repository = new JpaRepositoryFactory(em).getRepository(SampleEntityRepository.class);
|
||||
idClassRepository = new JpaRepositoryFactory(em).getRepository(SampleWithIdClassRepository.class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user