I’m running into an odd case where certain Spring Data JPA exists
repository queries are failing after upgrading to Hibernate ORM 6.2.3 or higher.
I have created a minimal Spring Boot project reproducing the issue here: GitHub - sdati/jpaexistsbug: Bug in Spring Data JPA 3.x / Hibernate 6.2.3
The problem seems to be caused by the following line of code - Specifically, this check returns false when using Spring Data JPA with certain derived queries:
&& ( resolvedModel = sqmPath.getResolvedModel() ) instanceof PersistentAttribute<?, ?>
Because the resolvedModel
value when using Spring Data JPA derived queries is not always an instance of PersistentAttribute - it is generally of type BasicSqmPathSource
I do recognize that this issue partly lies with how Spring Data JPA constructs its criteria, but this also seems to be a regression in behavior in Hibernate ORM, since it was working as expected prior to version 6.2.3.
The test case in the sample Spring Boot project includes documentation of the generated SQL vs what I would expect to be generated: https://github.com/sdati/jpaexistsbug/blob/main/src/test/java/com/example/jpaexistsbug/JpaexistsbugApplicationTests.java
// Fails when using Hibernate 6.2.3 or higher
//
// Generated SQL:
//
// select f1_0.id from fancy_item f1_0
// left join owner o1_0 on o1_0.id=f1_0.owner_id
// where o1_0.alive and f1_0.serial_number=? and f1_1.field1=?
// fetch first ? rows only
//
// Expected SQL:
//
// select f1_0.id from fancy_item f1_0
// inner join item f1_1 on f1_1.id=f1_0.id -- Should join to parent class for the WHERE f1_1.field1=?
// left join owner o1_0 on o1_0.id=f1_0.owner_id
// where o1_0.alive and f1_0.serial_number=? and f1_1.field1=?
// fetch first ? rows only
//
Any suggestions on ways to resolve? I can sort of work around this by doing a findFirstBy...() != null
rather than existsBy...
query in my repository, but I’d prefer to be able to use Spring Data JPA as designed.