Hibernate:Criteria查询花了很长时间与三级关系

时间:2015-11-26 21:34:37

标签: java hibernate criteria relationships

我在使用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

3 个答案:

答案 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缓存将拥有每个实体,然后,我认为,条件查询将更快。