[英]hibernate join fetch one to many multiple tables
I have the following entity relationship in my data model.我的数据 model 中有以下实体关系。
Entity A: one-to-many:Entity B
Entity B: one-to-many:Entity C
Entity B: one-to-many:Entity D
Hibernate Entities: 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;
}
Requirement: I want to query on Entity C with join fetch of Entity B and also eagerly fetch Entity D at the same time.要求:我想查询实体 C 和实体 B 的连接获取,同时也急切地获取实体 D。 After the query is completed I expect that if I do
entityC.getEntityB().getEntityDList()
, it should not lead to N+1 query problem in hibernate.查询完成后,我希望如果我执行
entityC.getEntityB().getEntityDList()
,它不应该导致 hibernate 中的 N+1 查询问题。
I was trying the following JPQL query:我正在尝试以下 JPQL 查询:
select ec from EntityC ec
join fetch ec.entityB eb
join fetch eb.entityD ed
where ec.id = :id
This leads to duplicates in the result because of cross join with Entity D. Instead of one result, I get n results where n is the size of list of Entity D.由于与实体 D 的交叉连接,这导致结果重复。我得到 n 个结果,而不是一个结果,其中 n 是实体 D 列表的大小。
How can I avoid this?我怎样才能避免这种情况? Is there any way to fetch the Entity D without cross join in JPQL?
有没有办法在 JPQL 中获取没有交叉连接的实体 D?
The first thing is to use the DISTINCT
JPQL keyword on your query, eg as:首先是在查询中使用
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);
// ^^^^^^^^
This will eliminate the duplicates but has the side-effect of passing the DISTINCT
to the SQL query as well, which is not something that you want.这将消除重复项,但也具有将
DISTINCT
传递给 SQL 查询的副作用,这不是您想要的。 Read details here , here and in this excellent answer.在此处、 此处和此出色答案中阅读详细信息。 Long story short - quoting Vlad Mihalcea's answer :
长话短说 - 引用 Vlad Mihalcea 的回答:
By passing DISTINCT to the SQL query, the EXECUTION PLAN is going to execute an extra Sort phase which adds overhead without bringing any value[...]
通过将 DISTINCT 传递给 SQL 查询,执行计划将执行额外的排序阶段,这会增加开销而不带来任何价值[...]
The solution is in the linked articles and answers, but in short, if you are on Hibernate >= 5.2.2, use the hibernate.query.passDistinctThrough
hint:解决方案在链接的文章和答案中,但简而言之,如果您使用的是 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.