一尘不染

使用JPA在Hibernate中使用EAGER类型的多次获取

tomcat

我有一个包含以下内容的实体:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "assessment")
@OrderBy(value = "order ASC")
private List<AssessmentPart> assessmentParts = new LinkedList<>();

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "assessment")
private List<AssessmentText> texts = new LinkedList<>();

如您所见,有两个集合需要急切加载。这不起作用,并且hibernate会引发异常:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

这是因为Hibernate无法一次性获取多个集合。但是,如果我将Listto SetLinkedListto
更改为HashSet这部分效果很好,但另一个问题发生了。

当我尝试使用以下方法从数据库中获取实体时:

entityManager.find(entityClass, primaryKey);

它失败并显示:

org.hibernate.AssertionFailure: null identifier

我确定传递给find方法的ID 不为null,我已经调试了,并且对此有把握。它以某种方式消失在hibernate状态。

如果我将集合类型更改为LAZY所有类型,则一切正常,没有错误,但是在某些情况下需要使用EAGER

有人有解决方案吗?我可以有一个集合,但可以防止发生断言错误,或者我可以有一个列表,但是以某种方式避免了多个提取包错误。

我在用:

Hibernate 4.2.2.Final
Tomcat 7
JPA 2.0
JDK 1.7

编辑

我刚刚发现,添加可以@Fetch(FetchMode.SELECT)解决该问题,并且可以使用带有EAGER类型的多个列表,但是仍然可以通过不使用特定于Hibernate的注释来解决此问题吗?以及为什么它首先解决了这个问题?


阅读 370

收藏
2020-06-16

共1个答案

一尘不染

问题的根本原因在于,当Hibernate提取SQL查询结果时,没有简单的方法来判断哪个子元素属于哪个集合。有关示例的更多详细说明。总结一下,您有以下解决方法:

  • 使用subselect分别加载每个集合 @Fetch(FetchMode.SELECT)
  • 通过添加索引列来强制使用列表而不是bag @IndexColumn(name="LIST_INDEX")
  • 使用无序集合(如Set)。
2020-06-16