I’m experimenting some issue while upgrading from SpringBoot 3.3.3 (Hibernate 6.5.2.Final) to SpringBoot 3.3.4+ (Hibernate 6.5.3 Final) with a duplicated left join expressions by Hibernate.
Currently I’m using SpringBoot 3.3.3 + Hibernate 6.5.2.Final, and I have a spring data JpaRepository method that use @EntityGraph and at same time filter by some attribute of the attribute defined as @EntityGraph.
Below is the code:
@Entity
@Table(name = "section")
public class Section {
@Id
private String id;
private String tenantId;
private String name;
@OneToMany(mappedBy = "section", cascade = CascadeType.ALL, orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<SectionFilter> filters = new ArrayList<>();
}
@Entity
@Table(name = "section_filter")
public class SectionFilter {
@Id
private String id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "sectionId")
private Section section;
private String name;
private boolean isSectionDefault;
}
public interface SectionRepository extends JpaRepository<Section, String> {
@EntityGraph(attributePaths = {"filters"})
Stream<SectionJPA> findAllByTenantIdAndFiltersIsSectionDefault(String tenantId, boolean isSectionDefault);
}
When I call this SectionRepository method with SpringBoot 3.3.3 + Hibernate 6.5.2.Final, the query generated by hibernate is:
select sj1_0.id,f1_0.sectionId,f1_0.id,f1_0.isSectionDefault,f1_0.name,sj1_0.name,sj1_0.tenantId
from customer_schema.qualityreview_sections sj1_0
left customer_schema.qualityreview_filters f1_0 on sj1_0.id=f1_0.sectionId
where sj1_0.tenantId=? and f1_0.isSectionDefault=? order by sj1_0.name
As you can see, it manages correctly the left join, so it detects that a join is needed by the query itself (findAllByTenantIdAndFiltersIsSectionDefault) but also by the @EntityGraph and is smart to use a single Left join.
However, when I migrate to SpringBoot 3.3.4 or higher + Hibernate 6.5.3.Final, the generated query by hibernate contains two Left Join, so we received more records than expected:
select sj1_0.id,f2_0.sectionId,f2_0.id,f2_0.isSectionDefault,f2_0.name,sj1_0.name,sj1_0.tenantId
from customer_schema.qualityreview_sections sj1_0
left join customer_schema.qualityreview_filters f1_0 on sj1_0.id=f1_0.sectionId
left join customer_schema.qualityreview_filters f2_0 on sj1_0.id=f2_0.sectionId
where sj1_0.tenantId=? and f1_0.isSectionDefault=? order by sj1_0.name
As the select is only filtering f1_0.isSectionDefault the other left join with table f2_0 is returning all the records without apply the filter.
Some clue or idea about what is happening?
Thanks