我有一个包含以下内容的实体:
@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无法一次性获取多个集合。但是,如果我将List
to Set
和LinkedList
to
更改为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的注释来解决此问题吗?以及为什么它首先解决了这个问题?
问题的根本原因在于,当Hibernate提取SQL查询结果时,没有简单的方法来判断哪个子元素属于哪个集合。有关示例的更多详细说明。总结一下,您有以下解决方法:
@Fetch(FetchMode.SELECT)
@IndexColumn(name="LIST_INDEX")