如何离开连接在Hibernate中获取多个子节点?

时间:2012-03-07 18:40:12

标签: hibernate hql fetch

我正在使用hibernate,我遇到了创建一个hql查询的问题,该查询会获取我对象的所有子项。

例如:对象用户有一个汽车列表和一个好友列表。

为了让用户获得他的汽车,我会使用以下查询:

from User u left join fetch u.cars where u.id = ?

这很好用,所以我觉得用户的汽车和他的朋友可以很容易地得到以下查询:

from User u left join fetch u.cars left join fetch u.friends where u.id = ?

但是这给了我以下错误:

  

HibernateException:无法同时获取多个包

现在我的问题是:在hibernate中获取多个子节点的正确方法是什么?

3 个答案:

答案 0 :(得分:12)

最多一个儿童集合必须是一个包(即声明为一个列表)。将其他集合声明为集合,它将起作用。

但是,请注意,执行此类提取连接会产生行的cartesiann产品。如果两个集合都有100个元素,则此类查询将从数据库中检索10,000行。执行获取一个集合的第一个查询和另一个获取另一个集合的第二个查询(有效地将检索到的行数减少到200个)更有效。这也是一种避免问题的方法:

select u from User u left join fetch u.cars where u.id = :id;
select u from User u left join fetch u.friends where u.id = :id;

答案 1 :(得分:8)

您只需点击收藏/列表(包)问题。

以下是Hibernate官方“问题”的链接:https://hibernate.atlassian.net/browse/HHH-1718。如你所见,它已于2006年开放并仍然开放。

除了JB Nizet建议的内容之外,我建议您在模型中使用Set而不是Collection或List(如果可以的话),否则,您也可以将Collection / List指定为FetchMode.SUBSELECT并作为最后一个选项(实施起来很痛苦),您可以在@ OneToMany / @ ManyToMany上使用@IndexColumn。

此博客文章将指导您实施解决方案:http://jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple

换句话说,除了解决方法之外,没有任何解决方案可以完全按照您的要求进行操作。

希望这有帮助!

编辑:拼写错误

答案 2 :(得分:0)

不可能,因为它对于应用程序/数据库来说太重了, 您需要创建2个单独的条件并单独检索数据。

Cat cat = sess.createCriteria(Cat.class)
              .add(Restrictions.like("name", "F%"))
              .uniqueResult();

List kitten = sess.createCriteria(Kitten.class)
                  .add(Restrictions.eq("cat", cat))
                  .createCriteria("kittens")
                  .add(Restrictions.like("name", "F%"))
                  .list();

List mate = sess.createCriteria(Mate.class)
                .add(Restrictions.eq("cat", cat))
                .createCriteria("mate")
                .add(Restrictions.like("name", "F%"))
                .list();