Java hibernate连接获取一对多的多个表

Java hibernate连接获取一对多的多个表,java,sql,hibernate,jpa,jpql,Java,Sql,Hibernate,Jpa,Jpql,我的数据模型中有以下实体关系 实体A:一对多:实体B 实体B:一对多:实体C 实体B:一对多:实体D 休眠实体: public class EntityA { private Integer id; @OneToMany private List<EntityB> entityBList; } public class EntityB { private Integer id; @ManyToOne

我的数据模型中有以下实体关系

实体A:一对多:实体B

实体B:一对多:实体C

实体B:一对多:实体D

休眠实体:

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;
}
这导致结果重复,因为与实体D交叉连接。我得到的不是一个结果,而是n个结果,其中n是实体D列表的大小


我怎样才能避免这种情况?有没有办法在JPQL中不交叉连接地获取实体D?

第一件事是在查询中使用
DISTINCT
JPQL关键字,例如:

TypedQuery query=em.createQuery(“从EntityC ec JOIN FETCH ec.entityB eb JOIN FETCH eb.entityDList ed中选择不同的ec,其中ec.id=:id”,EntityC.class);
//                                                 ^^^^^^^^
这将消除重复项,但也会产生副作用,将
DISTINCT
传递给SQL查询,这不是您想要的。阅读细节,并以出色的回答。长话短说-引用弗拉德·米哈尔恰的话:

通过将DISTINCT传递给SQL查询,执行计划将执行额外的排序阶段,这会增加开销,而不会带来任何值[…]

解决方案在链接的文章和答案中,但简而言之,如果您使用的是Hibernate>=5.2.2,请使用
Hibernate.query.passDistinctThrough
提示:

TypedQuery query=em.createQuery(“从EntityC ec JOIN FETCH ec.entityB eb JOIN FETCH eb.entityDList ed中选择不同的ec,其中ec.id=:id”,EntityC.class);
setHint(“hibernate.query.passDistinctThrough”,false);
//-或-
query.setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH,false);//导入org.hibernate.jpa.QueryHints
select ec from EntityC ec 
join fetch ec.entityB eb 
join fetch eb.entityD ed 
where ec.id = :id