gpt4 book ai didi

java - hibernate 生成查询,无需所有外连接获取

转载 作者:行者123 更新时间:2023-11-30 07:59:09 25 4
gpt4 key购买 nike

我有 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 {

}

简而言之,急切连接两组实体 B1 和 B2,每个实体急切连接(隐式)一个实体 C,而实体 C 又急切连接一组实体 D。

加载 A 对象时,生成的查询如下所示

select (...) from A a0 
left outer join B1 b1 on a0.id=b1.aid
left outer join C c1 on b1.cid=c1.id
left outer join D d1 on c1.id=d1.cid
left outer join B2 b2 on a0.id=b2.aid
left outer join C c2 on b2.cid=c2.id
where a0.id=?

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

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

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

感谢您的宝贵时间。

最佳答案

确实,这似乎是一个错误或一个不完整的功能。我也能够在更简单的场景中重现它:

@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 {

}

当通过 id 加载 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

因此,如果您确实想在一个查询中获取所有内容,则必须使用 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 亿行要快得多。

关于java - hibernate 生成查询,无需所有外连接获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32205065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com