I'm trying to create a spring data repository with a method to list a page of entities and a QueryDSL predicate using this:
public interface EntityRespository extends JpaRepository<Entity, Integer>, QueryDslPredicateExecutor<Entity> {
List<Entity> findAllBy(Predicate predicate, Pageable pageable);
}
As mentioned here Way to disable count query from PageRequest for getting total pages?, I'm tryng to use the "trick" naming the method with "findAllBy".
But when I invoke it, I'm getting this exception (it is trying to use the parameters as "parameters of the query"):
java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(ArrayList.java:834)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1067)
at org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:63)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:111)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:172)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:163)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:207)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:134)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:74)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:169)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:113)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:77)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:393)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:371)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy86.findAllBy(Unknown Source)
This exception doesn't occurs when I remove the Predicate, example:
List<Entity> findAllBy(Pageable pageable);
The question is:
How can I create a QueryDSL Repository with Pageable without emit the count query? Is more inexpensive to do an extra query to get the next page after the last page instead of emit an extra count query to each page request.
This is basically invalid usage of the query derivation mechanism. Executing
Predicate
instances and query methods are a distinct mechanisms that cannot be intermingled. You basically declare a query method that doesn't take any parameters (does not have any criterias) bit then takes aPredicate
thatUnfortunately the methods declared in repository base interfaces and
QueryDslPredicateExecutor
can only be redeclared to return more concrete types (e.g. overridingfindAll()
to returnList<T>
instead ofIterable<T>
as the implementation actually returns a type implementing that more concrete type).I suggest to create a custom implementation as described here.