如何在Hibernate中使用左连接获取多个子节点?

ars1skjm  于 2023-03-13  发布在  其他
关注(0)|答案(4)|浏览(130)

我正在使用hib,在创建一个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 = ?

但这会产生以下错误:
休眠异常:无法同时取出多个袋子
现在我的问题是:在休眠中获取多个子进程的正确方法是什么?

lawou6xi

lawou6xi1#

子集合中最多只能有一个是包(即声明为List)。将其他集合声明为Sets,它将正常工作。
但是要注意,这样的fetch连接会产生一个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;
whlutmcx

whlutmcx2#

您刚刚遇到了收集/列表(包)问题。
这里有一个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
换句话说,除了变通方法之外,没有解决方案可以完全实现您想要实现的目标。
希望这有帮助!
编辑:排印错误

t3psigkw

t3psigkw3#

这是不可能的,因为这对于应用程序/数据库来说太繁重了,您需要创建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();
ukqbszuj

ukqbszuj4#

如果您想获取更深的对象,可以尝试

from User u left join u.friends f left join fetch f.kids k where u.id = :id;
select u from User u left join fetch u.friends where u.id = :id;

在这里,您首先获取更深层次的子对象,然后获取主对象。
注意:获取深嵌套子代的第一个查询没有select

相关问题