From 0af9c62e04e5d2cf5be82c38461c58fd49cab0f6 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 17 Apr 2024 11:39:55 +0200 Subject: [PATCH] Fluent query API should use ProjectionFactory provided by the RepositoryFactory. This commit makes sure to push the ProjectionFactory down to the fluent query to make use of beans registered in the context. Prior to this change the fluent query variant would host its own factory not being aware of its surroundings. Original pull request: #3432 Closes: #3410 --- .../support/CrudMethodMetadata.java | 8 ++++++ .../CrudMethodMetadataPostProcessor.java | 26 ++++++++++++++++--- .../FetchableFluentQueryByPredicate.java | 23 +++++++++------- .../FetchableFluentQueryBySpecification.java | 25 ++++++++++-------- .../support/FluentQuerySupport.java | 11 ++++++-- .../support/JpaRepositoryFactory.java | 2 +- .../support/QuerydslJpaPredicateExecutor.java | 17 ++++++++++-- .../support/SimpleJpaRepository.java | 16 ++++++++++-- .../data/jpa/repository/GreetingsFrom.java | 26 +++++++++++++++++++ .../JavaConfigUserRepositoryTests.java | 5 ++++ .../jpa/repository/UserRepositoryTests.java | 26 +++++++++++++++++++ ...aPopulatingMethodInterceptorUnitTests.java | 7 ++--- ...chableFluentQueryByPredicateUnitTests.java | 2 +- .../test/resources/application-context.xml | 2 ++ .../config/namespace-application-context.xml | 2 ++ 15 files changed, 162 insertions(+), 36 deletions(-) create mode 100644 spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/GreetingsFrom.java diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java index b6cff2cd2..918e05b42 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadata.java @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.util.Optional; import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.projection.ProjectionFactory; import org.springframework.lang.Nullable; /** @@ -85,4 +86,11 @@ public interface CrudMethodMetadata { * @since 1.9 */ Method getMethod(); + + /** + * @return the {@link ProjectionFactory} to use or {@literal null} if not present. + * @since ?? + */ + @Nullable + ProjectionFactory getProjectionFactory(); } diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java index 9daa2377b..215855cb1 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java @@ -25,6 +25,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Predicate; +import java.util.function.Supplier; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -38,6 +39,7 @@ import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Meta; import org.springframework.data.jpa.repository.QueryHints; +import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor; import org.springframework.lang.Nullable; @@ -61,6 +63,11 @@ import org.springframework.util.ReflectionUtils; class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, BeanClassLoaderAware { private @Nullable ClassLoader classLoader = ClassUtils.getDefaultClassLoader(); + private final Supplier projectionFactorySupplier; + + CrudMethodMetadataPostProcessor(Supplier projectionFactorySupplier) { + this.projectionFactorySupplier = projectionFactorySupplier; + } @Override public void setBeanClassLoader(ClassLoader classLoader) { @@ -69,7 +76,8 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B @Override public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) { - factory.addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(repositoryInformation)); + factory + .addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(repositoryInformation, projectionFactorySupplier)); } /** @@ -101,11 +109,14 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B private final ConcurrentMap metadataCache = new ConcurrentHashMap<>(); private final Set implementations = new HashSet<>(); + private final Supplier projectionFactory; - CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation) { + CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation, + Supplier projectionFactory) { ReflectionUtils.doWithMethods(repositoryInformation.getRepositoryInterface(), implementations::add, method -> !repositoryInformation.isQueryMethod(method)); + this.projectionFactory = projectionFactory; } /** @@ -150,7 +161,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B if (methodMetadata == null) { - methodMetadata = new DefaultCrudMethodMetadata(method); + methodMetadata = new DefaultCrudMethodMetadata(method, projectionFactory.get()); CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata); if (tmp != null) { @@ -185,15 +196,17 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B private final @Nullable String comment; private final Optional entityGraph; private final Method method; + private ProjectionFactory projectionFactory; /** * Creates a new {@link DefaultCrudMethodMetadata} for the given {@link Method}. * * @param method must not be {@literal null}. */ - DefaultCrudMethodMetadata(Method method) { + DefaultCrudMethodMetadata(Method method, ProjectionFactory projectionFactory) { Assert.notNull(method, "Method must not be null"); + this.projectionFactory = projectionFactory; this.lockModeType = findLockModeType(method); this.queryHints = findQueryHints(method, it -> true); @@ -274,6 +287,11 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B public Method getMethod() { return method; } + + @Override + public ProjectionFactory getProjectionFactory() { + return projectionFactory; + } } private static class ThreadBoundTargetSource implements TargetSource { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicate.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicate.java index b6e51c290..91d9fc5bf 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicate.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicate.java @@ -34,6 +34,7 @@ import org.springframework.data.domain.ScrollPosition; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Window; import org.springframework.data.jpa.repository.query.ScrollDelegate; +import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.util.Assert; @@ -51,6 +52,7 @@ import com.querydsl.jpa.impl.AbstractJPAQuery; * @author Mark Paluch * @author Jens Schauder * @author J.R. Onyschak + * @author Christoph Strobl * @since 2.6 */ class FetchableFluentQueryByPredicate extends FluentQuerySupport implements FetchableFluentQuery { @@ -64,21 +66,21 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp private final Function existsOperation; private final EntityManager entityManager; - public FetchableFluentQueryByPredicate(Predicate predicate, Class entityType, + FetchableFluentQueryByPredicate(Predicate predicate, Class entityType, Function> finder, PredicateScrollDelegate scroll, BiFunction> pagedFinder, Function countOperation, - Function existsOperation, EntityManager entityManager) { + Function existsOperation, EntityManager entityManager, ProjectionFactory projectionFactory) { this(predicate, entityType, (Class) entityType, Sort.unsorted(), 0, Collections.emptySet(), finder, scroll, - pagedFinder, countOperation, existsOperation, entityManager); + pagedFinder, countOperation, existsOperation, entityManager, projectionFactory); } private FetchableFluentQueryByPredicate(Predicate predicate, Class entityType, Class resultType, Sort sort, int limit, Collection properties, Function> finder, PredicateScrollDelegate scroll, BiFunction> pagedFinder, Function countOperation, Function existsOperation, - EntityManager entityManager) { + EntityManager entityManager, ProjectionFactory projectionFactory) { - super(resultType, sort, limit, properties, entityType); + super(resultType, sort, limit, properties, entityType, projectionFactory); this.predicate = predicate; this.finder = finder; this.scroll = scroll; @@ -94,7 +96,8 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp Assert.notNull(sort, "Sort must not be null"); return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, this.sort.and(sort), limit, - properties, finder, scroll, pagedFinder, countOperation, existsOperation, entityManager); + properties, finder, scroll, pagedFinder, countOperation, existsOperation, entityManager, + getProjectionFactory()); } @Override @@ -103,7 +106,7 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp Assert.isTrue(limit >= 0, "Limit must not be negative"); return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, sort, limit, properties, finder, - scroll, pagedFinder, countOperation, existsOperation, entityManager); + scroll, pagedFinder, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override @@ -116,14 +119,15 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp } return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, sort, limit, properties, finder, - scroll, pagedFinder, countOperation, existsOperation, entityManager); + scroll, pagedFinder, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override public FetchableFluentQuery project(Collection properties) { return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, sort, limit, - mergeProperties(properties), finder, scroll, pagedFinder, countOperation, existsOperation, entityManager); + mergeProperties(properties), finder, scroll, pagedFinder, countOperation, existsOperation, entityManager, + getProjectionFactory()); } @Override @@ -230,7 +234,6 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp return getConversionFunction(entityType, resultType); } - static class PredicateScrollDelegate extends ScrollDelegate { private final ScrollQueryFactory scrollFunction; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryBySpecification.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryBySpecification.java index 57bec8597..b42399052 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryBySpecification.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryBySpecification.java @@ -36,6 +36,7 @@ import org.springframework.data.domain.Window; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.query.ScrollDelegate; import org.springframework.data.jpa.support.PageableUtils; +import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.query.FluentQuery; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.util.Assert; @@ -47,6 +48,7 @@ import org.springframework.util.Assert; * @param Domain type * @param Result type * @author Greg Turnquist + * @author Christoph Strobl * @since 3.0 */ class FetchableFluentQueryBySpecification extends FluentQuerySupport @@ -59,20 +61,21 @@ class FetchableFluentQueryBySpecification extends FluentQuerySupport private final Function, Boolean> existsOperation; private final EntityManager entityManager; - public FetchableFluentQueryBySpecification(Specification spec, Class entityType, - Function> finder, SpecificationScrollDelegate scrollDelegate, - Function, Long> countOperation, Function, Boolean> existsOperation, - EntityManager entityManager) { + FetchableFluentQueryBySpecification(Specification spec, Class entityType, Function> finder, + SpecificationScrollDelegate scrollDelegate, Function, Long> countOperation, + Function, Boolean> existsOperation, EntityManager entityManager, + ProjectionFactory projectionFactory) { this(spec, entityType, (Class) entityType, Sort.unsorted(), 0, Collections.emptySet(), finder, scrollDelegate, - countOperation, existsOperation, entityManager); + countOperation, existsOperation, entityManager, projectionFactory); } private FetchableFluentQueryBySpecification(Specification spec, Class entityType, Class resultType, Sort sort, int limit, Collection properties, Function> finder, SpecificationScrollDelegate scrollDelegate, Function, Long> countOperation, - Function, Boolean> existsOperation, EntityManager entityManager) { + Function, Boolean> existsOperation, EntityManager entityManager, + ProjectionFactory projectionFactory) { - super(resultType, sort, limit, properties, entityType); + super(resultType, sort, limit, properties, entityType, projectionFactory); this.spec = spec; this.finder = finder; this.scroll = scrollDelegate; @@ -87,7 +90,7 @@ class FetchableFluentQueryBySpecification extends FluentQuerySupport Assert.notNull(sort, "Sort must not be null"); return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, this.sort.and(sort), limit, - properties, finder, scroll, countOperation, existsOperation, entityManager); + properties, finder, scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override @@ -96,7 +99,7 @@ class FetchableFluentQueryBySpecification extends FluentQuerySupport Assert.isTrue(limit >= 0, "Limit must not be negative"); return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, this.sort.and(sort), limit, - properties, finder, scroll, countOperation, existsOperation, entityManager); + properties, finder, scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override @@ -108,14 +111,14 @@ class FetchableFluentQueryBySpecification extends FluentQuerySupport } return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, sort, limit, properties, finder, - scroll, countOperation, existsOperation, entityManager); + scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override public FetchableFluentQuery project(Collection properties) { return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, sort, limit, properties, finder, - scroll, countOperation, existsOperation, entityManager); + scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); } @Override diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FluentQuerySupport.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FluentQuerySupport.java index 4cc28c3df..d37cfd604 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FluentQuerySupport.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/FluentQuerySupport.java @@ -26,6 +26,7 @@ import java.util.function.Function; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.domain.ScrollPosition; import org.springframework.data.domain.Sort; +import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.lang.Nullable; @@ -36,6 +37,7 @@ import org.springframework.lang.Nullable; * @author Greg Turnquist * @author Jens Schauder * @author Mark Paluch + * @author Christoph Strobl * @since 2.6 */ abstract class FluentQuerySupport { @@ -46,10 +48,10 @@ abstract class FluentQuerySupport { protected final Set properties; protected final Class entityType; - private final SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory(); + private final ProjectionFactory projectionFactory; FluentQuerySupport(Class resultType, Sort sort, int limit, @Nullable Collection properties, - Class entityType) { + Class entityType, ProjectionFactory projectionFactory) { this.resultType = resultType; this.sort = sort; @@ -62,6 +64,11 @@ abstract class FluentQuerySupport { } this.entityType = entityType; + this.projectionFactory = projectionFactory; + } + + ProjectionFactory getProjectionFactory() { + return projectionFactory; } final Collection mergeProperties(Collection additionalProperties) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java index a0ec78a0c..0c0145026 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java @@ -100,7 +100,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { this.entityManager = entityManager; this.extractor = PersistenceProvider.fromEntityManager(entityManager); - this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(); + this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(() -> getProjectionFactory()); this.entityPathResolver = SimpleEntityPathResolver.INSTANCE; this.queryMethodFactory = new DefaultJpaQueryMethodFactory(extractor); this.queryRewriterProvider = QueryRewriterProvider.simple(); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java index 606d56631..3b3be3b72 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java @@ -36,9 +36,12 @@ import org.springframework.data.jpa.repository.query.KeysetScrollDelegate.QueryS import org.springframework.data.jpa.repository.query.KeysetScrollSpecification; import org.springframework.data.jpa.repository.support.FetchableFluentQueryByPredicate.PredicateScrollDelegate; import org.springframework.data.jpa.repository.support.FluentQuerySupport.ScrollQueryFactory; +import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.querydsl.EntityPathResolver; import org.springframework.data.querydsl.QSort; import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.lang.Nullable; @@ -223,7 +226,8 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto pagedFinder, // this::count, // this::exists, // - entityManager // + entityManager, // + getProjectionFactory() ); return queryFunction.apply((FetchableFluentQuery) fluentQuery); @@ -251,7 +255,6 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto AbstractJPAQuery query = doCreateQuery(getQueryHints().withFetchGraphs(entityManager), predicate); CrudMethodMetadata metadata = getRepositoryMethodMetadata(); - if (metadata == null) { return query; } @@ -331,6 +334,16 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto return querydsl.applySorting(sort, query).fetch(); } + private ProjectionFactory getProjectionFactory() { + + CrudMethodMetadata metadata = getRepositoryMethodMetadata(); + if(metadata == null || metadata.getProjectionFactory() == null) { + return new SpelAwareProxyProjectionFactory(); + } + + return metadata.getProjectionFactory(); + } + class QuerydslQueryStrategy implements QueryStrategy, BooleanExpression> { @Override diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 879e68386..c16727c9a 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -61,6 +61,8 @@ import org.springframework.data.jpa.repository.support.FetchableFluentQueryBySpe import org.springframework.data.jpa.repository.support.FluentQuerySupport.ScrollQueryFactory; import org.springframework.data.jpa.repository.support.QueryHints.NoHints; import org.springframework.data.jpa.support.PageableUtils; +import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.util.ProxyUtils; @@ -524,8 +526,8 @@ public class SimpleJpaRepository implements JpaRepositoryImplementation scrollDelegate = new SpecificationScrollDelegate<>(scrollFunction, entityInformation); - FetchableFluentQuery fluentQuery = new FetchableFluentQueryBySpecification<>(spec, domainClass, finder, - scrollDelegate, this::count, this::exists, this.entityManager); + FetchableFluentQueryBySpecification fluentQuery = new FetchableFluentQueryBySpecification<>(spec, domainClass, finder, + scrollDelegate, this::count, this::exists, this.entityManager, getProjectionFactory()); return queryFunction.apply((FetchableFluentQuery) fluentQuery); } @@ -903,6 +905,16 @@ public class SimpleJpaRepository implements JpaRepositoryImplementation users = repository.findBy( + of(prototype, + matching().withIgnorePaths("age", "createdAt", "active").withMatcher("firstname", + GenericPropertyMatcher::contains)), // + q -> q.as(UserProjectionUsingSpEL.class).all()); + + assertThat(users).extracting(UserProjectionUsingSpEL::hello) + .contains(new GreetingsFrom().groot(firstUser.getFirstname())); + } + @Test // GH-2294 void findByFluentExampleWithSimplePropertyPathsDoesntLoadUnrequestedPaths() { @@ -3364,4 +3384,10 @@ class UserRepositoryTests { private interface UserProjectionInterfaceBased { String getFirstname(); } + + private interface UserProjectionUsingSpEL { + + @Value("#{@greetingsFrom.groot(target.firstname)}") + String hello(); + } } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPopulatingMethodInterceptorUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPopulatingMethodInterceptorUnitTests.java index 143a3c15d..9824407c9 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPopulatingMethodInterceptorUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPopulatingMethodInterceptorUnitTests.java @@ -34,6 +34,7 @@ import org.mockito.quality.Strictness; import org.springframework.aop.framework.ProxyFactory; import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor.CrudMethodMetadataPopulatingMethodInterceptor; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -56,7 +57,7 @@ class CrudMethodMetadataPopulatingMethodInterceptorUnitTests { ProxyFactory factory = new ProxyFactory(new Object()); factory.addInterface(Sample.class); - factory.addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(information)); + factory.addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(information, SpelAwareProxyProjectionFactory::new)); factory.addAdvice(new MethodInterceptor() { @Override @@ -78,7 +79,7 @@ class CrudMethodMetadataPopulatingMethodInterceptorUnitTests { when(information.getRepositoryInterface()).thenReturn((Class) Sample.class); CrudMethodMetadataPopulatingMethodInterceptor interceptor = new CrudMethodMetadataPopulatingMethodInterceptor( - information); + information, () -> new SpelAwareProxyProjectionFactory()); interceptor.invoke(invocation); assertThat(TransactionSynchronizationManager.getResource(method)).isNull(); @@ -88,7 +89,7 @@ class CrudMethodMetadataPopulatingMethodInterceptorUnitTests { @SuppressWarnings("unchecked") void looksUpCrudMethodMetadataForEveryInvocation() { - CrudMethodMetadata metadata = new CrudMethodMetadataPostProcessor().getCrudMethodMetadata(); + CrudMethodMetadata metadata = new CrudMethodMetadataPostProcessor(() -> new SpelAwareProxyProjectionFactory()).getCrudMethodMetadata(); when(information.isQueryMethod(any())).thenReturn(false); when(information.getRepositoryInterface()).thenReturn((Class) Sample.class); diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicateUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicateUnitTests.java index 767ac14cb..f2c5e9f00 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicateUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByPredicateUnitTests.java @@ -35,7 +35,7 @@ class FetchableFluentQueryByPredicateUnitTests { Sort s1 = Sort.by(Order.by("s1")); Sort s2 = Sort.by(Order.by("s2")); FetchableFluentQueryByPredicate f = new FetchableFluentQueryByPredicate(null, null, null, null, null, null, null, - null); + null, null); f = (FetchableFluentQueryByPredicate) f.sortBy(s1).sortBy(s2); assertThat(f.sort).isEqualTo(s1.and(s2)); } diff --git a/spring-data-jpa/src/test/resources/application-context.xml b/spring-data-jpa/src/test/resources/application-context.xml index 74529a521..1bd58b22c 100644 --- a/spring-data-jpa/src/test/resources/application-context.xml +++ b/spring-data-jpa/src/test/resources/application-context.xml @@ -43,4 +43,6 @@ + + diff --git a/spring-data-jpa/src/test/resources/config/namespace-application-context.xml b/spring-data-jpa/src/test/resources/config/namespace-application-context.xml index e192050ec..b5c02d868 100644 --- a/spring-data-jpa/src/test/resources/config/namespace-application-context.xml +++ b/spring-data-jpa/src/test/resources/config/namespace-application-context.xml @@ -28,4 +28,6 @@ + +