我在使用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 {
...
}
My Criteria查询就像这样简单(实际上,会有一些过滤器,但它们没有被使用):
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
答案 0 :(得分:0)
您需要删除提取类型连接。渴望对你的数据布局很好,但你真的需要一次那么多的数据吗?
使用默认提取,hibernate将仅查询表A.然后,对于每个B的外键,每个键只查询一次B.同样为C.做
即,一旦从B获取b_id = 1,即使它与百万行A一起使用,它也不会被再次获取.Hibernate的第二级缓存处理它。
对于连接类型提取,对于A中的每一行,您将获得包含所有3个表的列的1个单行。
如果您的关系是OneToMany,那么您将获得返回的A x B x C行。但是自从ManyToOne以来,没有这样的问题。
你的问题甚至是这个查询为A的每个项返回1个大行,有太多的B和C复制。因此,数据库响应非常庞大,因此对于数据库和您的应用程序来说处理也很困难。
答案 1 :(得分:0)
嗯,实际上我觉得这个问题不是别的。我已将两种关系(A - > B和B - > C)更改为延迟(并删除了@Fetch)。然后我查询了一个特定的A对象。到现在为止还挺好。我能够获得该对象,并且我能够成功调用a.getB()。
尽管如此,当我调用b.getC()时,Hibernate不会将C对象返回给我(我的意思是,Hibernate会卡在这一行)。
当我调用b.getC()时,Hibernate创建的获取C对象的查询如下:
select
myCtable0_.id as id1_85_0_,
myCtable0_.name as nam2_85_0_
from
MyTableC myCtable0_
where
myCtable0_.id in (?, ?)
C表有一个id字段(主键)和一个名字(varchar)。
答案 2 :(得分:-1)
另一种选择是分别获取所有数据。然后,hibernate缓存将拥有每个实体,然后,我认为,条件查询将更快。