Predicates on plural paths operate on collection instead of joins
Working example https://github.com/xanscale/SpringDataBadJpqlGrammarException
- README.txt contains log with spring boot 4.0
- README_3.5.8.txt contains log with spring boot 3.5.8 that's works perfectly
org.springframework.data.jpa.repository.query.BadJpqlGrammarException: org.hibernate.query.PathException: Plural path 'com.example.demo.C(c).bbb' refers to a collection and so element attribute 'aaa' may not be referenced directly (use element() function); Bad SELECT c FROM C c WHERE c.bbb.aaa IS NOT EMPTY grammar [JPQL]
@xanscale thank you for getting in touch. If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
@christophstrobl updated issue with working example
@christophstrobl any news? @mp911de
Thanks for the report. This issue has been introduced through our switch from the Criteria API (that did the right thing) to JPQL. Interestingly, the generated HQL from a Criteria query (as used in Spring Data JPA 3.5.x) resembles the same path traversal syntax without incorporating element(…).
In any case, our way expressing nested property paths isn't in line with the JPA spec. Additionally, element(…) is Hibernate-specific so we should rather rewrite the query to a JOIN form via:
SELECT c FROM C c JOIN c.bbb b WHERE b.aaa IS NOT EMPTY
instead of:
SELECT c FROM C c WHERE c.bbb.aaa IS NOT EMPTY
@mp911de there is a way to log JPQL (not final SQL) generated from Spring JPA Query Methods ?
There is, set the logger org.springframework.data.jpa.repository.query.PartTreeJpaQuery to debug level, it will give you something along the lines of:
2025-12-11 14:21:26,638 DEBUG ta.jpa.repository.query.PartTreeJpaQuery: 235 - QueryPreparer: Derived query for query method [public abstract java.util.List org.springframework.data.jpa.repository.sample.UserRepository.findByFirstname(java.lang.String,org.springframework.data.domain.Pageable)]: 'SELECT u FROM User u WHERE u.firstname = :firstname'