抛出MultipleBagFetchException

我想在我的存储库层中有一个选项来急切加载entites,所以我尝试添加一个方法,该方法应该急切加载一个带有所有关系的问题实体,但它会抛出MultipleBagFetchException。 我怎样才能解决这个问题? 我正在使用Hibernate 4.16。

@NamedQuery(name = Question.FIND_BY_ID_EAGER, query = "SELECT q FROM Question q LEFT JOIN FETCH q.answers LEFT JOIN FETCH q.categories LEFT JOIN FETCH q.feedback LEFT JOIN FETCH q.participant WHERE q.id = :id"), 

我如何得到一个最初延迟加载的问题对象,急切地加载所有关系?

这在Hibernate中实际上是一个非常讨厌的问题,实际上是ORM。

会发生的是,许多(获取)连接会导致创建相当大的笛卡尔积。 即永远的其他连接新列和新行出现在结果中,导致(相当)大’方’结果。

Hibernate需要从此表中提取图形,但是将右列与正确的实体匹配并不够智能。

例如

假设我们有结果

 ABC ABD 

哪个需要成为:

  A | B /\ CD 

Hibernate可以从主键和一些编码魔法中扣除,图形必须是什么,但在实践中它需要明确的帮助来解决这个问题。

一种方法是在关系上指定Hibernate特定的@IndexColumn或JPA标准@OrderColumn

例如

 @Entity public class Question { @ManyToMany @JoinTable( name = "question_to_answer", joinColumns = @JoinColumn(name = "question_id"), inverseJoinColumns = @JoinColumn(name = "answer_id") ) @IndexColumn(name = "answer_order") private List answers; // ... } 

在这个例子中,我使用了一个连接表,还有一个额外的列answer_order 。 通过此列,每个问题/答案关系具有唯一的序列号,Hibernate可以区分结果表中的条目并创建所需的对象图。

一个注意事项,如果它涉及多个实体,使用如此多的热切联接可能会导致比您根据所涉及的实体数量想象的更大的结果集。

进一步阅读:

  • Hibernateexception – 同时获取多个行李1
  • Hibernateexception – 同时获取多个行李2
  • 解决同时获取多个包 – 使用@IndexColumn