From 0086b3847763ea00cecf25228ac7e091503b7bc7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 19 Apr 2024 11:19:27 +0200 Subject: [PATCH] Polishing. Migrate configuration setters for repository instances into JpaRepositoryConfigurationAware interface. Revert ProjectionFactory propagation through CrudMethodMetadata. Original pull request: #3432 See: #3410 --- .../support/CrudMethodMetadata.java | 7 --- .../CrudMethodMetadataPostProcessor.java | 26 ++------- .../FetchableFluentQueryByPredicate.java | 9 ++- .../FetchableFluentQueryBySpecification.java | 8 +-- .../support/FluentQuerySupport.java | 8 +-- .../JpaRepositoryConfigurationAware.java | 55 +++++++++++++++++++ .../support/JpaRepositoryFactory.java | 26 ++++++--- .../support/JpaRepositoryImplementation.java | 19 +------ .../support/QuerydslJpaPredicateExecutor.java | 28 ++++++---- .../support/SimpleJpaRepository.java | 19 ++++--- ...aPopulatingMethodInterceptorUnitTests.java | 11 ++-- 11 files changed, 125 insertions(+), 91 deletions(-) create mode 100644 spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryConfigurationAware.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 918e05b42..ae738974b 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,7 +21,6 @@ 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; /** @@ -87,10 +86,4 @@ public interface CrudMethodMetadata { */ 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 215855cb1..246e82dcd 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,10 +25,10 @@ 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; + import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -39,7 +39,6 @@ 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; @@ -63,11 +62,6 @@ 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) { @@ -76,8 +70,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B @Override public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) { - factory - .addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(repositoryInformation, projectionFactorySupplier)); + factory.addAdvice(new CrudMethodMetadataPopulatingMethodInterceptor(repositoryInformation)); } /** @@ -109,14 +102,11 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B private final ConcurrentMap metadataCache = new ConcurrentHashMap<>(); private final Set implementations = new HashSet<>(); - private final Supplier projectionFactory; - CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation, - Supplier projectionFactory) { + CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation) { ReflectionUtils.doWithMethods(repositoryInformation.getRepositoryInterface(), implementations::add, method -> !repositoryInformation.isQueryMethod(method)); - this.projectionFactory = projectionFactory; } /** @@ -161,7 +151,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B if (methodMetadata == null) { - methodMetadata = new DefaultCrudMethodMetadata(method, projectionFactory.get()); + methodMetadata = new DefaultCrudMethodMetadata(method); CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata); if (tmp != null) { @@ -196,17 +186,15 @@ 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, ProjectionFactory projectionFactory) { + DefaultCrudMethodMetadata(Method method) { Assert.notNull(method, "Method must not be null"); - this.projectionFactory = projectionFactory; this.lockModeType = findLockModeType(method); this.queryHints = findQueryHints(method, it -> true); @@ -288,10 +276,6 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B 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 91d9fc5bf..9ed0a0ce3 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 @@ -96,8 +96,7 @@ 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, - getProjectionFactory()); + properties, finder, scroll, pagedFinder, countOperation, existsOperation, entityManager, projectionFactory); } @Override @@ -106,7 +105,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, getProjectionFactory()); + scroll, pagedFinder, countOperation, existsOperation, entityManager, projectionFactory); } @Override @@ -119,7 +118,7 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp } return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, sort, limit, properties, finder, - scroll, pagedFinder, countOperation, existsOperation, entityManager, getProjectionFactory()); + scroll, pagedFinder, countOperation, existsOperation, entityManager, projectionFactory); } @Override @@ -127,7 +126,7 @@ class FetchableFluentQueryByPredicate extends FluentQuerySupport imp return new FetchableFluentQueryByPredicate<>(predicate, entityType, resultType, sort, limit, mergeProperties(properties), finder, scroll, pagedFinder, countOperation, existsOperation, entityManager, - getProjectionFactory()); + projectionFactory); } @Override 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 b42399052..6121be437 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 @@ -90,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, getProjectionFactory()); + properties, finder, scroll, countOperation, existsOperation, entityManager, projectionFactory); } @Override @@ -99,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, getProjectionFactory()); + properties, finder, scroll, countOperation, existsOperation, entityManager, projectionFactory); } @Override @@ -111,14 +111,14 @@ class FetchableFluentQueryBySpecification extends FluentQuerySupport } return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, sort, limit, properties, finder, - scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); + scroll, countOperation, existsOperation, entityManager, projectionFactory); } @Override public FetchableFluentQuery project(Collection properties) { return new FetchableFluentQueryBySpecification<>(spec, entityType, resultType, sort, limit, properties, finder, - scroll, countOperation, existsOperation, entityManager, getProjectionFactory()); + scroll, countOperation, existsOperation, entityManager, projectionFactory); } @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 d37cfd604..5917a119f 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 @@ -27,7 +27,6 @@ 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; /** @@ -47,8 +46,7 @@ abstract class FluentQuerySupport { protected final int limit; protected final Set properties; protected final Class entityType; - - private final ProjectionFactory projectionFactory; + protected final ProjectionFactory projectionFactory; FluentQuerySupport(Class resultType, Sort sort, int limit, @Nullable Collection properties, Class entityType, ProjectionFactory projectionFactory) { @@ -67,10 +65,6 @@ abstract class FluentQuerySupport { this.projectionFactory = projectionFactory; } - ProjectionFactory getProjectionFactory() { - return projectionFactory; - } - final Collection mergeProperties(Collection additionalProperties) { Set newProperties = new HashSet<>(); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryConfigurationAware.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryConfigurationAware.java new file mode 100644 index 000000000..d5b497f9a --- /dev/null +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryConfigurationAware.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.support; + +import org.springframework.data.jpa.repository.query.EscapeCharacter; +import org.springframework.data.projection.ProjectionFactory; + +/** + * Interface to be implemented by classes that want to be aware of their configuration in a JPA repository context. + * + * @author Mark Paluch + * @since 3.3 + */ +public interface JpaRepositoryConfigurationAware { + + /** + * Configures the {@link EscapeCharacter} to be used with the repository. + * + * @param escapeCharacter must not be {@literal null}. + */ + default void setEscapeCharacter(EscapeCharacter escapeCharacter) { + + } + + /** + * Configures the {@link ProjectionFactory} to be used with the repository. + * + * @param projectionFactory must not be {@literal null}. + */ + default void setProjectionFactory(ProjectionFactory projectionFactory) { + + } + + /** + * Configures the {@link CrudMethodMetadata} to be used with the repository. + * + * @param metadata must not be {@literal null}. + */ + default void setRepositoryMethodMetadata(CrudMethodMetadata metadata) { + + } +} 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 0c0145026..bffdafd46 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 @@ -83,6 +83,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { private final EntityManager entityManager; private final QueryExtractor extractor; private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor; + private final CrudMethodMetadata crudMethodMetadata; private EntityPathResolver entityPathResolver; private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT; @@ -100,7 +101,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { this.entityManager = entityManager; this.extractor = PersistenceProvider.fromEntityManager(entityManager); - this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(() -> getProjectionFactory()); + this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(); this.entityPathResolver = SimpleEntityPathResolver.INSTANCE; this.queryMethodFactory = new DefaultJpaQueryMethodFactory(extractor); this.queryRewriterProvider = QueryRewriterProvider.simple(); @@ -116,6 +117,8 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { if (extractor.equals(PersistenceProvider.ECLIPSELINK)) { addQueryCreationListener(new EclipseLinkProjectionQueryCreationListener(entityManager)); } + + this.crudMethodMetadata = crudMethodMetadataPostProcessor.getCrudMethodMetadata(); } @Override @@ -192,8 +195,8 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { protected final JpaRepositoryImplementation getTargetRepository(RepositoryInformation information) { JpaRepositoryImplementation repository = getTargetRepository(information, entityManager); - repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata()); - repository.setEscapeCharacter(escapeCharacter); + + invokeAwareMethods(repository); return repository; } @@ -249,8 +252,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { @Override protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) { - return getRepositoryFragments(metadata, entityManager, entityPathResolver, - crudMethodMetadataPostProcessor.getCrudMethodMetadata()); + return getRepositoryFragments(metadata, entityManager, entityPathResolver, this.crudMethodMetadata); } /** @@ -279,13 +281,23 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { "Cannot combine Querydsl and reactive repository support in a single interface"); } - return RepositoryFragments.just(new QuerydslJpaPredicateExecutor<>(getEntityInformation(metadata.getDomainType()), - entityManager, resolver, crudMethodMetadata)); + QuerydslJpaPredicateExecutor querydslJpaPredicateExecutor = new QuerydslJpaPredicateExecutor<>( + getEntityInformation(metadata.getDomainType()), entityManager, resolver, crudMethodMetadata); + invokeAwareMethods(querydslJpaPredicateExecutor); + + return RepositoryFragments.just(querydslJpaPredicateExecutor); } return RepositoryFragments.empty(); } + private void invokeAwareMethods(JpaRepositoryConfigurationAware repository) { + + repository.setRepositoryMethodMetadata(crudMethodMetadata); + repository.setEscapeCharacter(escapeCharacter); + repository.setProjectionFactory(getProjectionFactory()); + } + private static boolean isTransactionNeeded(Class repositoryClass) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(repositoryClass); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryImplementation.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryImplementation.java index 9984675ac..d3a5b1c5f 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryImplementation.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryImplementation.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.support; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.query.EscapeCharacter; import org.springframework.data.repository.NoRepositoryBean; /** @@ -28,21 +27,7 @@ import org.springframework.data.repository.NoRepositoryBean; * @author Jens Schauder */ @NoRepositoryBean -public interface JpaRepositoryImplementation extends JpaRepository, JpaSpecificationExecutor { +public interface JpaRepositoryImplementation + extends JpaRepository, JpaSpecificationExecutor, JpaRepositoryConfigurationAware { - /** - * Configures the {@link CrudMethodMetadata} to be used with the repository. - * - * @param crudMethodMetadata must not be {@literal null}. - */ - void setRepositoryMethodMetadata(CrudMethodMetadata crudMethodMetadata); - - /** - * Configures the {@link EscapeCharacter} to be used with the repository. - * - * @param escapeCharacter Must not be {@literal null}. - */ - default void setEscapeCharacter(EscapeCharacter escapeCharacter) { - - } } 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 3b3be3b72..c16f95c0a 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 @@ -41,7 +41,6 @@ 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; @@ -74,14 +73,15 @@ import com.querydsl.jpa.impl.AbstractJPAQuery; * @author Greg Turnquist * @author Yanming Zhou */ -public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecutor { +public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecutor, JpaRepositoryConfigurationAware { private final JpaEntityInformation entityInformation; private final EntityPath path; private final Querydsl querydsl; private final QuerydslQueryStrategy scrollQueryAdapter; private final EntityManager entityManager; - private final CrudMethodMetadata metadata; + private @Nullable CrudMethodMetadata metadata; + private @Nullable ProjectionFactory projectionFactory; /** * Creates a new {@link QuerydslJpaPredicateExecutor} from the given domain class and {@link EntityManager} and uses @@ -103,6 +103,16 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto this.scrollQueryAdapter = new QuerydslQueryStrategy(); } + @Override + public void setRepositoryMethodMetadata(CrudMethodMetadata metadata) { + this.metadata = metadata; + } + + @Override + public void setProjectionFactory(ProjectionFactory projectionFactory) { + this.projectionFactory = projectionFactory; + } + @Override public Optional findOne(Predicate predicate) { @@ -199,7 +209,7 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto select = (AbstractJPAQuery) querydsl.applySorting(sort, select); if (scrollPosition instanceof OffsetScrollPosition offset) { - if(!offset.isInitial()) { + if (!offset.isInitial()) { select.offset(offset.getOffset() + 1); } } @@ -227,8 +237,7 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto this::count, // this::exists, // entityManager, // - getProjectionFactory() - ); + getProjectionFactory()); return queryFunction.apply((FetchableFluentQuery) fluentQuery); } @@ -336,12 +345,11 @@ public class QuerydslJpaPredicateExecutor implements QuerydslPredicateExecuto private ProjectionFactory getProjectionFactory() { - CrudMethodMetadata metadata = getRepositoryMethodMetadata(); - if(metadata == null || metadata.getProjectionFactory() == null) { - return new SpelAwareProxyProjectionFactory(); + if (projectionFactory == null) { + projectionFactory = new SpelAwareProxyProjectionFactory(); } - return metadata.getProjectionFactory(); + return projectionFactory; } class QuerydslQueryStrategy implements QueryStrategy, BooleanExpression> { 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 c16727c9a..50afeee8a 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 @@ -105,6 +105,7 @@ public class SimpleJpaRepository implements JpaRepositoryImplementation implements JpaRepositoryImplementation implements JpaRepositoryImplementation implements JpaRepositoryImplementation new SpelAwareProxyProjectionFactory()); + information); interceptor.invoke(invocation); assertThat(TransactionSynchronizationManager.getResource(method)).isNull(); @@ -89,7 +88,7 @@ class CrudMethodMetadataPopulatingMethodInterceptorUnitTests { @SuppressWarnings("unchecked") void looksUpCrudMethodMetadataForEveryInvocation() { - CrudMethodMetadata metadata = new CrudMethodMetadataPostProcessor(() -> new SpelAwareProxyProjectionFactory()).getCrudMethodMetadata(); + CrudMethodMetadata metadata = new CrudMethodMetadataPostProcessor().getCrudMethodMetadata(); when(information.isQueryMethod(any())).thenReturn(false); when(information.getRepositoryInterface()).thenReturn((Class) Sample.class);