From 9468e890dec374300ca3b66d5f0e389269623cfe Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 22 Apr 2021 11:02:45 +0200 Subject: [PATCH] Introduce template method for easier customization of fragments. We introduced getRepositoryFragments(RepositoryMetadata,EntityManager,EntityPathResolver,CrudMethodMetadata) to easier get hold of typical arguments required for customization of repository base fragments that aren't bound to a specific entity type such as QuerydslJpaPredicateExecutor. Closes #2202. --- .../support/JpaRepositoryFactory.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java index 50adefde9..2a1795bac 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jpa.repository.support; +import static org.springframework.data.querydsl.QuerydslUtils.*; + import java.io.Serializable; import java.lang.reflect.Method; import java.util.Optional; @@ -23,6 +25,7 @@ import java.util.stream.Stream; import javax.persistence.EntityManager; import javax.persistence.Tuple; +import com.querydsl.core.types.EntityPath; import org.slf4j.Logger; import org.springframework.beans.factory.BeanFactory; @@ -45,9 +48,8 @@ import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.QueryCreationListener; -import org.springframework.data.repository.core.support.RepositoryComposition; +import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments; import org.springframework.data.repository.core.support.RepositoryFactorySupport; -import org.springframework.data.repository.core.support.RepositoryFragment; import org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor; import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; @@ -57,8 +59,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; -import static org.springframework.data.querydsl.QuerydslUtils.*; - /** * JPA specific generic repository factory. * @@ -234,9 +234,27 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getRepositoryFragments(org.springframework.data.repository.core.RepositoryMetadata) */ @Override - protected RepositoryComposition.RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) { + protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) { - RepositoryComposition.RepositoryFragments fragments = RepositoryComposition.RepositoryFragments.empty(); + return getRepositoryFragments(metadata, entityManager, entityPathResolver, + crudMethodMetadataPostProcessor.getCrudMethodMetadata()); + } + + /** + * Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add JPA-specific extensions. Typically + * adds a {@link QuerydslJpaPredicateExecutor} if the repository interface uses Querydsl. + *

+ * Can be overridden by subclasses to customize {@link RepositoryFragments}. + * + * @param metadata repository metadata. + * @param entityManager the entity manager. + * @param resolver resolver to translate an plain domain class into a {@link EntityPath}. + * @param crudMethodMetadata metadata about the invoked CRUD methods. + * @return + * @since 2.5.1 + */ + protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata, EntityManager entityManager, + EntityPathResolver resolver, CrudMethodMetadata crudMethodMetadata) { boolean isQueryDslRepository = QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(metadata.getRepositoryInterface()); @@ -248,15 +266,11 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { "Cannot combine Querydsl and reactive repository support in a single interface"); } - JpaEntityInformation entityInformation = getEntityInformation(metadata.getDomainType()); - - Object querydslFragment = getTargetRepositoryViaReflection(QuerydslJpaPredicateExecutor.class, entityInformation, - entityManager, entityPathResolver, crudMethodMetadataPostProcessor.getCrudMethodMetadata()); - - fragments = fragments.append(RepositoryFragment.implemented(querydslFragment)); + return RepositoryFragments.just(new QuerydslJpaPredicateExecutor<>(getEntityInformation(metadata.getDomainType()), + entityManager, resolver, crudMethodMetadata)); } - return fragments; + return RepositoryFragments.empty(); } private static boolean hasMethodReturningStream(Class repositoryClass) {