[英]hibernate join fetch one to many multiple tables
我的數據 model 中有以下實體關系。
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.