Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic projections in combination with Specifications and Pagination not working [DATAJPA-1189] #1524

Closed
spring-projects-issues opened this issue Sep 27, 2017 · 11 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@spring-projects-issues
Copy link

Marcel Overdijk opened DATAJPA-1189 and commented

Dynamic Projections in combination with Specifications and/or Pagination is not working.

<T> Collection<T> findProjectedBy(Specification<Customer> spec, Class<T> projection);

<T> Page<T> findPagedProjectedBy(Specification<Customer> spec, Pageable pageable, Class<T> projection);

Calling these methods will throw a

java.util.NoSuchElementException
	at java.util.ArrayList$Itr.next(ArrayList.java:854)
	at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042)
	at org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:65)
	at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101)
	at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161)
	at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152)
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:229)
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:150)
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:79)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:121)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
	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:282)
	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$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
	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.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
	at com.sun.proxy.$Proxy66.findProjectedBy(Unknown Source)
	at example.springdata.jpa.projections.CustomerRepositoryIntegrationTest.supportsDynamicProjectionInCombinationWitSpecification(CustomerRepositoryIntegrationTest.java:153)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)



Affects: 1.11.7 (Ingalls SR7)

Issue Links:

  • DATAJPA-1453 findDistinct + Specification = Failed to create query
    ("is duplicated by")
  • DATAJPA-1532 Select / Multiselect Not Working with toPredicate method of Specification
    ("is duplicated by")
  • DATAJPA-289 Add findAll(Predicate, Pageable) method to QueryDslPredicateExecutor that returns only List/Iterable

27 votes, 21 watchers

@spring-projects-issues
Copy link
Author

Marcel Overdijk commented

I created a PR for this here spring-projects/spring-data-examples#296 which contains 2 failing tests.

This is related to https://jira.spring.io/browse/DATAJPA-393 and https://jira.spring.io/browse/DATAJPA-749 (I cannot link the issues)

@spring-projects-issues
Copy link
Author

Marcel Overdijk commented

Might be the same issue as https://jira.spring.io/browse/DATAJPA-1185 but good to check by adding tests for it

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Just as dynamic Querydsl predicates aren't supported with query methods, Specification s aren't either. I.e. that's got nothing to do with projections, Specification is simply not supported as query method parameter type. The reason is that it'd raise the question how those specifications are combined with the static query part contained in the method or the @Query annotation

@spring-projects-issues
Copy link
Author

Marcel Overdijk commented

OK thx for confirming Specification s are not working with query methods.
I understand this has nothing to do with projections directly, but it does mean you can't query a (dynamic) projection with a Querydsl Predicate or Specification. Or is there another way?
I need Predicate s or Specification s as filters are not know upfront and creating many query methods like will become unmanageable

@spring-projects-issues
Copy link
Author

Marcel Overdijk commented

Would it be an idea to extend the PagingAndSortingRepository with a findAll(Pageable pageable, Class<T> projection) to make this work?
Same for the JpaSpecificationExecutor and QueryDslPredicateExecutor.

That way we could use (dynamic) projections with both predicates and specifications. Don't know what this means technically....

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

That indeed is an option but one that ship with the downside of having to touch all these interfaces and implementations. I've been wondering whether we could rather plug support for predicates and specifications in a special query execution mode that rejects combined usages. I guess that's something for a bit of R&D time after Kay GA :)

@spring-projects-issues
Copy link
Author

Marcel Overdijk commented

(y)

@spring-projects-issues
Copy link
Author

this9is3me commented

Hi, any updates on this bug?

Thank you

@spring-projects-issues
Copy link
Author

Ruslan Stelmachenko commented

That indeed is an option but one that ship with the downside of having to touch all these interfaces and implementations.

Maybe it is worth to add another interface for these methods to not create backward incompatibility. And maybe add a base interface that extends both old interface and new interface.

Adding support for predicates and specifications in a special query execution mode is also a good thing that is worth to be implemented, but I think in majority of cases a couple of signatures like this is more than enough:

<T> Page<T> findAll(@Nullable Specification<T> spec, Class<T> projection, Pageable pageable);

(basically, all methods of current JpaSpecificationExecutor interface and similar methods of QuerydslPredicateExecutor interface)

In most cases, if we already specified a predicate/specification and a projection, what else custom method parameters (except paging/sorting specifiers) would we want to specify?

 

By the way, it would be a very useful feature. Currently you could create methods with flexible predicates, or with flexible fields to select. But you couldn't combine these features. This makes zero-code approach impossible to be used in many cases and leads to necessity to create a custom implementation of such methods, that duplicates half of the spring-data

@spring-projects-issues spring-projects-issues added type: bug A general bug in: core Issues in core support has: votes-jira labels Dec 30, 2020
@schauder schauder added status: pending-design-work Needs design work before any code can be developed type: enhancement A general enhancement and removed type: bug A general bug labels Feb 26, 2021
@mp911de mp911de removed the status: pending-design-work Needs design work before any code can be developed label Jul 29, 2021
@mp911de
Copy link
Member

mp911de commented Jul 29, 2021

Linking #2269 as that design could enable projections when using JPA specifications.

@gregturn
Copy link
Contributor

As Ollie has described, this combination of features is simply not supported, so I'm closing this issue.

@gregturn gregturn closed this as not planned Won't fix, can't repro, duplicate, stale Aug 10, 2023
@gregturn gregturn added status: declined A suggestion or change that we don't feel we should currently apply and removed in: core Issues in core support type: enhancement A general enhancement has: votes-jira labels Aug 10, 2023
@gregturn gregturn self-assigned this Aug 10, 2023
@gregturn gregturn added status: invalid An issue that we don't feel is valid and removed status: declined A suggestion or change that we don't feel we should currently apply labels Aug 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants