- Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
type: enhancementA general enhancementA general enhancement
Milestone
Description
I would like to write my own QueryDslExecutor to return a Slice instead of a Page e.g. Slice readAll. However, the QueryDslExecutor is hard coded in the factory.
@Override protected RepositoryComposition.RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) { RepositoryComposition.RepositoryFragments fragments = RepositoryComposition.RepositoryFragments.empty(); boolean isQueryDslRepository = QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(metadata.getRepositoryInterface()); if (isQueryDslRepository) { if (metadata.isReactiveRepository()) { throw new InvalidDataAccessApiUsageException( "Cannot combine Querydsl and reactive repository support in a single interface"); } JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType()); Object querydslFragment = getTargetRepositoryViaReflection(QuerydslJpaPredicateExecutor.class, entityInformation, entityManager, entityPathResolver, crudMethodMetadataPostProcessor.getCrudMethodMetadata()); fragments = fragments.append(RepositoryFragment.implemented(querydslFragment)); } return fragments; }
In addition, there is no way to override the getTargetRepositoryViaReflection.
protected final <R> R getTargetRepositoryViaReflection(Class<?> baseClass, Object... constructorArguments) { Optional<Constructor<?>> constructor = ReflectionUtils.findConstructor(baseClass, constructorArguments); return constructor.map(it -> (R) BeanUtils.instantiateClass(it, constructorArguments)) .orElseThrow(() -> new IllegalStateException(String.format( "No suitable constructor found on %s to match the given arguments: %s. Make sure you implement a constructor taking these", baseClass, Arrays.stream(constructorArguments).map(Object::getClass).collect(Collectors.toList())))); }
No member variable has a getter, so you have to rely entirely on reflection.
The (ugly) workaround looks like this
@Override protected RepositoryComposition.RepositoryFragments getRepositoryFragments( final RepositoryMetadata metadata ) { RepositoryComposition.RepositoryFragments fragments = RepositoryComposition.RepositoryFragments.empty(); final boolean isQueryDslRepository = QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom( metadata.getRepositoryInterface() ); if ( isQueryDslRepository ) { if ( metadata.isReactiveRepository() ) { throw new InvalidDataAccessApiUsageException( "Cannot combine Querydsl and reactive repository support in a single interface" ); } final JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation( metadata.getDomainType() ); final Field entityManagerField = ReflectionUtils.findField( getClass(), "entityManager" ); final Field entityPathResolverField = ReflectionUtils.findField( getClass(), "entityPathResolver" ); final Field crudMethodMetadataPostProcessorField = ReflectionUtils .findField( getClass(), "crudMethodMetadataPostProcessor" ); final EntityManager entityManager = (EntityManager) ReflectionUtils.getField( entityManagerField, this ); final EntityPathResolver entityPathResolver = (EntityPathResolver) ReflectionUtils .getField( entityPathResolverField, this ); final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor = (CrudMethodMetadataPostProcessor) ReflectionUtils .getField( crudMethodMetadataPostProcessorField, this ); final Object querydslFragment = getTargetRepositoryViaReflection( MySliceableRepositoryImpl.class, entityInformation, entityManager, entityPathResolver, crudMethodMetadataPostProcessor.getCrudMethodMetadata() ); fragments = fragments.append( RepositoryFragment.implemented( querydslFragment ) ); } return fragments; }
There should be an easier way to provide a custom executor.
Metadata
Metadata
Assignees
Labels
type: enhancementA general enhancementA general enhancement