使用 JPA 在 Hibernate 中使用 EAGER 类型进行多次提取 [英] Multiple fetches with EAGER type in Hibernate with JPA

查看:40
本文介绍了使用 JPA 在 Hibernate 中使用 EAGER 类型进行多次提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体,其中包含:

I have an entity which contains:

@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<>();

如您所见,有两个集合需要立即加载.这不起作用,休眠会引发异常:

as you see there are two collections which needs to be eagerly loaded. This is not working and hibernate throws an exception:

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

那是因为 Hibernate 无法一次性获取多个集合.但是,如果我将 List 更改为 Set 并将 LinkedList 更改为 HashSet 这部分工作正常,但其他 - 更多出现烦人的问题.

That's because Hibernate can't fetch multiple collections with one go. But if I change the List to Set and the LinkedList to HashSet this part works fine but the other - more annoying issue occurs.

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

When I am trying to get the entity from the database using:

entityManager.find(entityClass, primaryKey);

它失败了:

org.hibernate.AssertionFailure: null identifier

我确信我传递给 find 方法的 ID 不为空,我已经调试过并且我确信这一点.它以某种方式消失在 Hibernate 中.

I am sure that ID I am passing to find method is not null, I've debugged and I am sure of this. It somehow disappears inside Hibernate.

如果我将集合类型更改为 LAZY 一切正常而不会出错,但在某些情况下我需要使用 EAGER.

If I change collection types to LAZY everything just works without errors but there are some circumstances where I need to use EAGER.

有没有人有解决办法?要么我可以有一个集合但防止发生断言错误,或者我可以有一个列表但以某种方式避免多个 fetch bag 错误.

Does anybody have a solution how to fix it? Either I could have a set but prevent assertion error from occurring or I could have a list but somehow avoid multiple fetch bags error.

我正在使用:

Hibernate 4.2.2.Final
Tomcat 7
JPA 2.0
JDK 1.7

编辑

我刚刚发现添加 @Fetch(FetchMode.SELECT) 解决了这个问题,我可以使用 EAGER 类型的多个列表,但无论如何都可以解决这是通过不使用 Hibernate 特定的注释?为什么它首先解决了这个问题?

I've just discovered that adding @Fetch(FetchMode.SELECT) fixes the issue and I can use multiple list with EAGER type, but is there anyway to solve this by not using Hibernate specific annotations? And why it fixed the issue in the first place?

推荐答案

问题的根源在于,Hibernate 在获取 SQL 查询结果时,没有简单的方法可以判断哪个子元素属于哪个集合.请参阅此博客条目以获取更详细的说明和示例.总而言之,您有以下解决方法:

The root cause of the problem is that when Hibernate fetches SQL query results there is no simple way to tell which child element belongs to which collection. See this blog entry for more detailed explanation with an example. To summarize you have following workarounds:

  • 使用子选择分别加载每个集合 @Fetch(FetchMode.SELECT)
  • 通过添加索引列强制使用列表而不是包@IndexColumn(name="LIST_INDEX")
  • 使用无序集合,如 Set.

这篇关于使用 JPA 在 Hibernate 中使用 EAGER 类型进行多次提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆