Hi,
We are updating from Spring Boot 2 to 3 (Hibernate 5 to Hibernate 6) and have a problem where Hibernate 6 is generating a subquery for joins on fields with multiple @JoinColumn
annotations which is causing a performance regression. Our queries have gone from taking milliseconds to seconds.
We are using Oracle Database.
Example test case:
Person
:
@Entity
@Table(name = "people")
public class Person {
@Id
@JdbcTypeCode(Types.VARCHAR)
@Column(name = "id")
private UUID id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
}
Book
:
@Entity
@Table(name = "books")
public class Book {
@Id
@JdbcTypeCode(Types.VARCHAR)
@Column(name = "id")
private UUID id;
@ManyToOne
@JoinColumn(name = "owner_first_name", referencedColumnName = "first_name", insertable = false, updatable = false)
@JoinColumn(name = "owner_last_name", referencedColumnName = "last_name", insertable = false, updatable = false)
private Person owner;
}
JPQL query:
SELECT 1
FROM Person p
JOIN Book b ON b.owner = p
Hibernate 6 generated query:
select
1
from
people p1_0
join
books b1_0
on (b1_0.owner_first_name, b1_0.owner_last_name) in (select
p1_0.first_name, p1_0.last_name
from
dual)
As you can see, the join is using an IN
clause with a subquery selecting from dual
. Hibernate 5 did not do this.
Interestingly, if I comment out one of the @JoinColumn
annotations, it does not generate the IN
clause and the join is generated as expected:
select
1
from
people p1_0
join
books b1_0
on b1_0.owner_first_name=p1_0.first_name
Is this expected behaviour with Hibernate 6 and is there any way we can avoid it if so, or does it look like a bug?