[英]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.