【发布时间】:2019-11-09 15:46:20
【问题描述】:
由于 MultipleBagFetchException,我无法执行简单的 fetchjoin。
@Entity
public class Person {
@OneToMany(mappedBy="person",fetch=FetchType.LAZY)
private List<Auto> autos;
}
@Entity
public class Auto {
@ManyToOne
@JoinColumn(name = "person_id", nullable = false)
private Person person;
@OneToMany(mappedBy="auto",fetch=FetchType.LAZY)
private List<Tool> tools;
}
@Entity
@Table(name="tool")
public class Tool {
@ManyToOne
@JoinColumn(name = "auto_id", nullable = false)
private Auto auto;
}
如您所见,我所有的关联都使用默认的 fetchtype。
@Query("SELECT p FROM Person p JOIN FETCH p.autos a JOIN FETCH a.tools")
List<Person>findAll();
结果:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [com.example.entities.Person.autos, com.example.entities.Auto.tools]
我已阅读过有关此异常的信息,但在这些情况下,此异常的原因是对集合使用了 EAGER 提取类型。那这个呢?这是最简单的Entity关系。
最重要的是,假设我们不允许触摸实体。 仅在查询端如何解决?
【问题讨论】:
-
在多个集合提取的情况下解决 MultipleBagFetchException 并非易事。请注意,在您的查询中,您急切地获取多个集合(JOIN FETCH)。 [参考这个答案](stackoverflow.com/questions/13334831/…) 可能的解决方案。您可以尝试不加入 FETCH 工具,让它在访问时延迟加载。或者如果实体可以更新,则将列表更改为设置。
-
所以如果我们不想接触实体本身,基本上不可能避免这种情况下的 n+1 个查询?