spring-data-jpa icon indicating copy to clipboard operation
spring-data-jpa copied to clipboard

Predicates on plural paths operate on collection instead of joins

Open xanscale opened this issue 1 month ago • 6 comments

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 avatar Dec 02 '25 18:12 xanscale

@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 avatar Dec 02 '25 21:12 christophstrobl

@christophstrobl updated issue with working example

xanscale avatar Dec 03 '25 13:12 xanscale

@christophstrobl any news? @mp911de

xanscale avatar Dec 06 '25 19:12 xanscale

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 avatar Dec 11 '25 10:12 mp911de

@mp911de there is a way to log JPQL (not final SQL) generated from Spring JPA Query Methods ?

xanscale avatar Dec 11 '25 13:12 xanscale

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'

mp911de avatar Dec 11 '25 13:12 mp911de