-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Paged findAll(…) with Specification does not work with join fetch [DATAJPA-105] #532
Comments
Andrew Geery commented The way I've handled this is to use the CriteriaQuery.getResultType() method to check whether the query's projection is Long or the class the Specification is operating on. If the resultType is Long, the query is a count and no join fetches should be used. If the resultType is the class the Specification is operating on, it's a normal query and fetch joins can be used |
Oliver Drotbohm commented So I assume you're calling |
Andrew Geery commented I think I tried that approach (wiping out the fetches Set) and it didn't work for Hibernate (I think the Set was not mutable). The approach I came up with is simpler :). From the CriterQuery object which is passed into the toPredicate() method, look at the resultType. If the resultType is a Long, the specification is being used as a count query and thus shouldn't have any fetches associated with it. If the resultType is not a Long, the specification is being used for a regular "data" query and fetches can be used. So it is up to each Specification definition to handle its own fetches and to not include the fetches (via an if statement) if it's being used for counting |
Thomas Darimont commented Hello, I just verified that the proposed solution works: @SuppressWarnings("unused")
@Test
public void testPagedSpecificationProjection() {
Specification<Person> spec = new Specification<Person>() {
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
if (Long.class != query.getResultType()) {
root.fetch(Person_.addresses);
}
return cb.conjunction();
}
};
Pageable pageable = new PageRequest(0, 1);
Page<Person> page = personRepo.findAll(spec, pageable);
} Best regards, |
Jens Schauder commented If I read the comments correct: There exists a solution to the problem which can be implemented in the The solution Spring Data JPA could provide would result either in a leaky abstraction or recreating a significant part of the Criteria API which we don't want to maintain. I therefore close this issue |
any updates on that? |
Hello @schauder Is there any update on this? |
👀 |
is there any update |
2024 => any update ? |
When using Kotlin you could use an extension function to get rid of the if statement in the specification. For example:
|
Hi @schauder, any update on it? |
@anaconda875 , this issue appears as "closed" already! |
Andrew Geery opened DATAJPA-105 and commented
The method
Page<T> findAll(Specification<T>, Pageable)
in theJpaSpecificationExecutor
interface throws an exception if theSpecification
uses a join fetch. The problem is that in order to do the pagination, the library has to first perform a count query, but when the count query is performed, the join fetches are not eliminated or changed to regular joins.The error is:
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
The attached zip file is a simple Maven project which demonstrates this problem (mvn test).
Affects: 1.0 GA, 1.0.1
Attachments:
14 votes, 11 watchers
The text was updated successfully, but these errors were encountered: