一尘不染

Hibernate抛出MultipleBagFetchException

hibernate

我想在我的存储库层中有一个选项来渴望加载实体,所以我尝试添加一种方法来渴望加载具有所有关系的问题实体,但是它会抛出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"),

我如何获得一个最初是延迟加载的问题对象,以期渴望加载所有关系?


阅读 170

收藏
2020-06-20

共1个答案

一尘不染

在Hibernate和通常的ORM中,这是一个相当棘手的问题。

发生的情况是,许多(提取)连接导致创建了相当大的笛卡尔积。也就是说,其他任何联接都会在结果中出现新的列和新的行,从而导致(相当大的)“正方形”结果。

Hibernate需要从该表中提取图形,但是它不足以将正确的列与正确的实体进行匹配。

例如

假设我们有结果

A B C
A B D

需要成为:

 A
 |
 B
 /\
C  D

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<Answer> answers;

    // ...
}

在此示例中,我使用的是带有额外column的联接表answer_order。通过此列(每个Question /
Answer关系具有唯一的序号),Hibernate可以区分结果表中的条目并创建所需的对象图。

顺便说一句,如果它涉及多个实体,那么使用如此多的热切连接可能会导致结果集比您根据所涉及的实体数所想的要大得多。

进一步阅读:

2020-06-20