我不明白为什么 Hibernate 创建一个有两个连接的查询

I don't understand why Hibernate creates a query with two joins

我有两个具有多对多关系的实体。

@Entity
@Table(name = "KATEGORIA_CENOWA_WODA_SCIEKI")
public class KategoriaCenowaWodaScieki extends BaseEntity {

   private static final long serialVersionUID = -113600254855102844L;

  @EqualsAndHashCode.Exclude
  @ManyToMany(mappedBy = "kategoriaCenowaList")
  private Set<KatalogSubstancjiWodaScieki> katalogSubstancjiList = new HashSet<>();

@Entity
@Table(name = "KATALOG_SUBSTANCJI_WODA_SCIEKI")
public class KatalogSubstancjiWodaScieki extends BaseEntity {

  private Integer kodSubstancji;

  @Column(nullable = false) 
  private String nazwaSubstancji;

  @EqualsAndHashCode.Exclude
  @ManyToMany
  @JoinTable(name = "KATALOG_SUBSTANCJI_WODA_SCIEKI_KATEGORIA_CENOWA_WODA_SCIEKI",
    joinColumns = {
      @JoinColumn(name = "KATALOG_SUBSTANCJI_ID")},
    inverseJoinColumns = {
      @JoinColumn(name = "KATEGORIA_CENOWA_ID")})
  private Set<KategoriaCenowaWodaScieki> kategoriaCenowaList = new HashSet<>();

并且我创建了一个包含一个连接的查询

@Query("select s.kategoriaCenowaList from KatalogSubstancjiWodaScieki s " +
        "inner join s.kategoriaCenowaList c " +
        " where s = :katalogSubstancji " ) 
Optional<KategoriaCenowaWodaScieki> findByKatalogSubstancjiAndOkresObowiazywaniaAndKatalogRZGW(
        KatalogSubstancjiWodaScieki katalogSubstancji);

我不明白为什么生成的 SQL 包含两个物理连接。也许有人可以解释一下?

select
    kategoriac4_.ID as ID1_46_,
    kategoriac4_.CREATED as CREATED2_46_,
    kategoriac4_.UPDATED as UPDATED3_46_,
    kategoriac4_.KATALOG_RZGW_ID as KATALOG_9_46_,
    kategoriac4_.kod as kod4_46_,
    kategoriac4_.nazwa as nazwa5_46_,
    kategoriac4_.dataDo as dataDo6_46_,
    kategoriac4_.dataOd as dataOd7_46_,
    kategoriac4_.stawka as stawka8_46_
from
    KATALOG_SUBSTANCJI_WODA_SCIEKI katalogsub0_
      inner join
    KATALOG_SUBSTANCJI_WODA_SCIEKI_KATEGORIA_CENOWA_WODA_SCIEKI kategoriac1_
    on katalogsub0_.ID=kategoriac1_.KATALOG_SUBSTANCJI_ID
        inner join
    KATEGORIA_CENOWA_WODA_SCIEKI kategoriac2_
    on kategoriac1_.KATEGORIA_CENOWA_ID=kategoriac2_.ID

因为@ManyToMany。该注释仅适用于 2 个连接,就像它在 SQL 中一样。

您无法在没有 2 个联接的 Many-To-Many 关系中查询数据。第一个连接转到连接 table,它包含对 2 个基 table 的引用以及您要连接的实际数据。然后第二个连接查询第二个 table.

的实际数据

KATALOG_SUBSTANCJI_WODA_SCIEKI 是基数 table。那你加入 KATALOG_SUBSTANCJI_WODA_SCIEKI_KATEGORIA_CENOWA_WODA_SCIEKI 保存实体之间的引用,然后 KATEGORIA_CENOWA_WODA_SCIEKI 保存第二组实际数据。

即使查询中没有您的连接,hibernate 也应该执行这 2 个连接以完全加载实体。