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

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

问题描述

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

  @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL,mappedBy =评估)
@OrderBy(值=订单ASC)
私人列表< AssessmentPart> assessmentParts = new LinkedList<>();

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

如您所见,有两个需要急切加载的集合。这不起作用,Hibernate会抛出一个异常:

 引起:org.hibernate.loader.MultipleBagFetchException:不能同时获取多个包

这是因为Hibernate无法一次获取多个集合。但如果我将 List 更改为 Set ,并且 LinkedList HashSet 这部分工作正常,但另一个 - 更恼人的问题发生。

当我试图获得实体从数据库使用:

  entityManager.find(entityClass,primaryKey); 

失败:

  org.hibernate.AssertionFailure:null标识符

我确定ID I我传递给 find 方法不为null,我已经调试过了,我确信这一点。它不知何故在Hibernate中消失。



如果我将集合类型更改为 LAZY 在这种情况下,我需要使用 EAGER



有人有解决方法如何解决它吗?要么我可以有一个集合,但防止出现断言错误,或者我可以有一个列表,但不知何故避免多个提取袋错误。



我正在使用:

  Hibernate 4.2.2.Final 
Tomcat 7
JPA 2.0
JDK 1.7

编辑

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

解决方案问题的根本原因在于,当Hibernate提取SQL查询结果时没有简单的方法来确定哪个子元素属于哪个集合。请参阅此博客文章,以获取更详细的解释和示例。总而言之,您有以下解决方法:


  • 使用subselect @Fetch(FetchMode.SELECT)分别加载每个集合 code>

  • 通过添加索引列来强制使用列表而不是bag。 @IndexColumn(name =LIST_INDEX)

  • 使用像Set这样的无序集合。


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

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

It fails with:

org.hibernate.AssertionFailure: null identifier

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.

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

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.

I am using:

Hibernate 4.2.2.Final
Tomcat 7
JPA 2.0
JDK 1.7

EDIT

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?

解决方案

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:

  • Load each collection separately using subselect @Fetch(FetchMode.SELECT)
  • Force usage of list instead of bag by adding index column @IndexColumn(name="LIST_INDEX")
  • Use unordered collection like Set.

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

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