Skip to content

Commit 8717db6

Browse files
committed
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
1 parent 192ba02 commit 8717db6

File tree

3 files changed

+19
-40
lines changed

3 files changed

+19
-40
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public AbstractJpaQuery(JpaQueryMethod method, EntityManager em) {
9292
if (method.isStreamQuery()) {
9393
return new StreamExecution();
9494
} else if (method.isProcedureQuery()) {
95-
return new ProcedureExecution();
95+
return new ProcedureExecution(method.isCollectionQuery());
9696
} else if (method.isCollectionQuery()) {
9797
return new CollectionExecution();
9898
} else if (method.isSliceQuery()) {

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java

+17-37
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public abstract class JpaQueryExecution {
6868

6969
conversionService.addConverter(JpaResultConverters.BlobToByteArrayConverter.INSTANCE);
7070
conversionService.removeConvertible(Collection.class, Object.class);
71-
potentiallyRemoveOptionalConverter(conversionService);
71+
conversionService.removeConvertible(Object.class, Optional.class);
7272

7373
CONVERSION_SERVICE = conversionService;
7474
}
@@ -197,7 +197,7 @@ static class PagedExecution extends JpaQueryExecution {
197197

198198
@Override
199199
@SuppressWarnings("unchecked")
200-
protected Object doExecute(final AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
200+
protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
201201

202202
Query query = repositoryQuery.createQuery(accessor);
203203

@@ -324,41 +324,41 @@ protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccesso
324324
*/
325325
static class ProcedureExecution extends JpaQueryExecution {
326326

327+
private final boolean collectionQuery;
328+
327329
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";
328330

331+
ProcedureExecution(boolean collectionQuery) {
332+
this.collectionQuery = collectionQuery;
333+
}
334+
329335
@Override
330336
protected Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAccessor accessor) {
331337

332338
Assert.isInstanceOf(StoredProcedureJpaQuery.class, jpaQuery);
333339

334-
StoredProcedureJpaQuery storedProcedureJpaQuery = (StoredProcedureJpaQuery) jpaQuery;
335-
336-
StoredProcedureQuery storedProcedure = storedProcedureJpaQuery.createQuery(accessor);
340+
StoredProcedureJpaQuery query = (StoredProcedureJpaQuery) jpaQuery;
341+
StoredProcedureQuery procedure = query.createQuery(accessor);
337342

338343
try {
339344

340-
boolean returnsResultSet = storedProcedure.execute();
345+
boolean returnsResultSet = procedure.execute();
341346

342347
if (returnsResultSet) {
343348

344349
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) {
345350
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
346351
}
347352

348-
if (storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) {
349-
return storedProcedure.getResultList();
350-
} else {
351-
return storedProcedure.getSingleResult();
352-
}
353+
return collectionQuery ? procedure.getResultList() : procedure.getSingleResult();
353354
}
354355

355-
return storedProcedureJpaQuery.extractOutputValue(storedProcedure);
356-
356+
return query.extractOutputValue(procedure);
357357
} finally {
358358

359-
if (storedProcedure instanceof AutoCloseable autoCloseable) {
359+
if (procedure instanceof AutoCloseable ac) {
360360
try {
361-
autoCloseable.close();
361+
ac.close();
362362
} catch (Exception ignored) {}
363363
}
364364
}
@@ -375,10 +375,10 @@ static class StreamExecution extends JpaQueryExecution {
375375

376376
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";
377377

378-
private static Method streamMethod = ReflectionUtils.findMethod(Query.class, "getResultStream");
378+
private static final Method streamMethod = ReflectionUtils.findMethod(Query.class, "getResultStream");
379379

380380
@Override
381-
protected Object doExecute(final AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
381+
protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
382382

383383
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) {
384384
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
@@ -399,24 +399,4 @@ protected Object doExecute(final AbstractJpaQuery query, JpaParametersParameterA
399399
}
400400
}
401401

402-
/**
403-
* Removes the converter being able to convert any object into an {@link Optional} from the given
404-
* {@link ConversionService} in case we're running on Java 8.
405-
*
406-
* @param conversionService must not be {@literal null}.
407-
*/
408-
public static void potentiallyRemoveOptionalConverter(ConfigurableConversionService conversionService) {
409-
410-
ClassLoader classLoader = JpaQueryExecution.class.getClassLoader();
411-
412-
if (ClassUtils.isPresent("java.util.Optional", classLoader)) {
413-
414-
try {
415-
416-
Class<?> optionalType = ClassUtils.forName("java.util.Optional", classLoader);
417-
conversionService.removeConvertible(Object.class, optionalType);
418-
419-
} catch (ClassNotFoundException | LinkageError o_O) {}
420-
}
421-
}
422402
}

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.data.jpa.repository.support;
1717

18-
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.*;
1919

2020
import jakarta.persistence.EntityManager;
2121
import jakarta.persistence.PersistenceContext;
@@ -59,7 +59,6 @@ class JpaRepositoryTests {
5959

6060
@BeforeEach
6161
void setUp() {
62-
6362
repository = new JpaRepositoryFactory(em).getRepository(SampleEntityRepository.class);
6463
idClassRepository = new JpaRepositoryFactory(em).getRepository(SampleWithIdClassRepository.class);
6564
}

0 commit comments

Comments
 (0)