簡體   English   中英

hibernate join 獲取一對多表

[英]hibernate join fetch one to many multiple tables

我的數據 model 中有以下實體關系。

ERD

Entity A: one-to-many:Entity B

Entity B: one-to-many:Entity C

Entity B: one-to-many:Entity D

Hibernate 實體:

public class EntityA {
    
    private Integer id;
    
    @OneToMany
    private List<EntityB> entityBList;
}

public class EntityB {
    
    private Integer id;

    @ManyToOne
    private EntityA entityA;
    
    @OneToMany(fetch=FetchType.LAZY)
    private List<EntityC> entityCList;

    @OneToMany(fetch=FetchType.LAZY)
    private List<EntityD> entityDList;
}

public class EntityC {
    
    private Integer id;
    
    @ManyToOne
    private EntityB entityB;
}

public class EntityD {

    private Integer id;

    @ManyToOne
    private EntityB entityB;
}

要求:我想查詢實體 C 和實體 B 的連接獲取,同時也急切地獲取實體 D。 查詢完成后,我希望如果我執行entityC.getEntityB().getEntityDList() ,它不應該導致 hibernate 中的 N+1 查詢問題。

我正在嘗試以下 JPQL 查詢:

select ec from EntityC ec 
join fetch ec.entityB eb 
join fetch eb.entityD ed 
where ec.id = :id

由於與實體 D 的交叉連接,這導致結果重復。我得到 n 個結果,而不是一個結果,其中 n 是實體 D 列表的大小。

我怎樣才能避免這種情況? 有沒有辦法在 JPQL 中獲取沒有交叉連接的實體 D?

首先是在查詢中使用DISTINCT JPQL 關鍵字,例如:

TypedQuery<EntityC> query = em.createQuery("SELECT DISTINCT ec FROM EntityC ec JOIN FETCH ec.entityB eb JOIN FETCH eb.entityDList ed WHERE ec.id = :id", EntityC.class);
//                                                 ^^^^^^^^

這將消除重復項,但也具有將DISTINCT傳遞給 SQL 查詢的副作用,這不是您想要的。 在此處此處出色答案中閱讀詳細信息。 長話短說 - 引用 Vlad Mihalcea 的回答

通過將 DISTINCT 傳遞給 SQL 查詢,執行計划將執行額外的排序階段,這會增加開銷而不帶來任何價值[...]

解決方案在鏈接的文章和答案中,但簡而言之,如果您使用的是 Hibernate >= 5.2.2,請使用hibernate.query.passDistinctThrough提示:

TypedQuery<EntityC> query = em.createQuery("SELECT DISTINCT ec FROM EntityC ec JOIN FETCH ec.entityB eb JOIN FETCH eb.entityDList ed WHERE ec.id = :id", EntityC.class);
query.setHint("hibernate.query.passDistinctThrough", false);
// -OR-
query.setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false); // import org.hibernate.jpa.QueryHints

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM