我在使用 Criteria 查找属于某个实体的所有对象时遇到问题。我的模型如下(仅显示相关代码):
@Entity...
Class A {
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "ide_b", referencedColumnName = "ide_b", nullable = false)
private B b;
}
@Entity...
class B {
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "ide_c", referencedColumnName = "ide_c", nullable = false)
private C c;
}
@Entity...
class C {
...
}
我的条件查询就像这样简单(实际上,会有一些过滤器,但它们没有被使用):
Criteria criteria = getSession().createCriteria(A.class);
criteria.list(); // MY SYSTEM STAYS HERE FOREVER WHEN RUNNING AGAINST A REAL DATABASE
有人知道这个问题吗?系统永远停留在“criteria.list()”线上并且永远不会返回。
我已经测试了它直接在数据库上生成的 SQL,它运行得很好。
我已经使用仅涉及 A 类引用 B 和类 A 引用 C(直接)的代码测试了此查询。他们都工作。关联中的第三级似乎引起了问题...注意:我的 Hibernate 版本是旧版本,例如 3.0.0
最佳答案
您需要删除获取类型连接。 Eager 对于您的数据布局来说很好,但是您真的一次需要那么多数据吗?
使用默认的 fetch,hibernate 将只查询表 A。然后对于每个 B 的外键,每个键仅查询 B 一次。对 C 也做同样的事情。
即,一旦从 B 获取 b_id=1,即使它与 A 的百万行一起使用,也不会再次获取。Hibernate 的二级缓存会处理它。
使用连接类型获取,对于 A 中的每一行,您将获得 1 个包含所有 3 个表的列的单行。
如果您的关系是 OneToMany,那么您将返回 A x B x C 行。但自从ManyToOne之后,就不存在这样的问题了。
您的问题是,即使此查询为 A 处的每个项目返回 1 个大行,但 B 和 C 复制太多。因此数据库响应巨大,因此对于数据库和您的应用程序来说处理也很困难。
关于java - Hibernate:三级关系的条件查询需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33947317/