Java hibernate生成查询,无需所有外部连接获取

Java hibernate生成查询,无需所有外部连接获取,java,hibernate,join,Java,Hibernate,Join,我有5个实体: @Entity public class A { @OneToMany(mappedBy="a", fetch=FetchType.EAGER) @Fetch(FetchMode.JOIN) private Set<B1> b1s; @OneToMany(mappedBy="a", fetch=FetchType.EAGER) @Fetch(FetchMode.JOIN) private Set<B2> b

我有5个实体:

@Entity
public class A {
    @OneToMany(mappedBy="a", fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Set<B1> b1s;

    @OneToMany(mappedBy="a", fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Set<B2> b2s;
}

@Entity
public class B1 {
    @ManyToOne
    @JoinColumn(name="c")
    private C c;
}

@Entity
public class B2 {
    @ManyToOne
    @JoinColumn(name="c")
    private C c;
}

@Entity
public class C {
    @OneToMany(mappedBy="d", fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Set<D> ds;
}

@Entity
public classD {

}
问题在于,链接到c2的实体D集(通过B2实体加载的C实体)未加载到同一查询中,导致每个c2对象的N个后续查询

我希望Hibernate在第一次查询中为这些对象生成另一个左外部联接,正如它在第一次出现D时所做的那样

我错过了什么?我在Oracle数据库上使用hibernate 3.6,这是一个已知问题吗


谢谢您的时间。

事实上,这似乎是一个bug或一个不完整的功能。我还能够在一个更简单的场景中重现它:

@Entity
public class A {
    @OneToMany(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn
    private Set<B> bs1;

    @OneToMany(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn
    private Set<B> bs2;
}

@Entity
public class B {
    @OneToMany(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn
    private Set<C> cs;
}

@Entity
public class C {

}
因此,如果您真的想在一个查询中获取所有内容,则必须使用HQL:

select a from A a 
left join fetch a.b1s b1 
left join fetch b1.c c1 
left join fetch c1.ds 
left join fetch a.b2s b2 
left join fetch b2.c c2 
left join fetch c2.ds 
where a.id = ?
但是,我假设加入的集合非常小。因为这些类型的联接产生完全笛卡尔积,被认为是非常糟糕的反模式

假设每个集合仅包含100行(
A
有100个
b1s
和100个
b2s
,并且
b1s
b2s
中的每个集合都有一个
C
,其中有100个
ds
)。然后,您将获得并读取包含1亿行的结果集


但以惰性集合和批处理抓取为例,在几个查询中总共读取约400行,这比在一个查询中读取1亿行要快得多。

查询一个a返回的行数非常少。我的问题是A是批量获取的,因此我不能使用HQL加载它,也不能在原始HQL查询中查询A及其子实体,因为它将返回太多(大)行
from
    A a0_ 
left outer join
    B bs1x1_ 
        on a0_.id=bs1x1_.bs1_id 
left outer join
    C cs2_ 
        on bs1x1_.id=cs2_.cs_id 
left outer join
    B bs2x3_ 
        on a0_.id=bs2x3_.bs2_id 
select a from A a 
left join fetch a.b1s b1 
left join fetch b1.c c1 
left join fetch c1.ds 
left join fetch a.b2s b2 
left join fetch b2.c c2 
left join fetch c2.ds 
where a.id = ?