Java Hibernate 抛出 MultipleBagFetchException - 不能同时获取多个包
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4334970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate throws MultipleBagFetchException - cannot simultaneously fetch multiple bags
提问by blow
Hibernate throws this exception during SessionFactory creation:
Hibernate 在 SessionFactory 创建期间抛出这个异常:
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包
This is my test case:
这是我的测试用例:
Parent.java
父程序
@Entity
public Parent {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
// @IndexColumn(name="INDEX_COL") if I had this the problem solve but I retrieve more children than I have, one child is null.
private List<Child> children;
}
Child.java
子程序
@Entity
public Child {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Parent parent;
}
How about this problem? What can I do?
这个问题怎么样?我能做什么?
EDIT
编辑
OK, the problem I have is that another "parent" entity is inside my parent, my real behavior is this:
好的,我遇到的问题是另一个“父”实体在我的父内部,我的真实行为是这样的:
Parent.java
父程序
@Entity
public Parent {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private AnotherParent anotherParent;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
private List<Child> children;
}
AnotherParent.java
另一个父类
@Entity
public AnotherParent {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
private List<AnotherChild> anotherChildren;
}
Hibernate doesn't like two collections with FetchType.EAGER
, but this seems to be a bug, I'm not doing unusual things...
Hibernate 不喜欢用 两个集合FetchType.EAGER
,但这似乎是一个错误,我没有做不寻常的事情......
Removing FetchType.EAGER
from Parent
or AnotherParent
solves the problem, but I need it, so real solution is to use @LazyCollection(LazyCollectionOption.FALSE)
instead of FetchType
(thanks to Bozhofor the solution).
删除FetchType.EAGER
从Parent
或AnotherParent
解决问题,但我需要它,所以真正的解决方案是使用@LazyCollection(LazyCollectionOption.FALSE)
的,而不是FetchType
(感谢Bozho的解决方案)。
采纳答案by Bozho
I think a newer version of hibernate (supporting JPA 2.0) should handle this. But otherwise you can work it around by annotating the collection fields with:
我认为更新版本的 hibernate(支持 JPA 2.0)应该可以解决这个问题。但除此之外,您可以通过使用以下方法注释集合字段来解决此问题:
@LazyCollection(LazyCollectionOption.FALSE)
Remember to remove the fetchType
attribute from the @*ToMany
annotation.
请记住fetchType
从@*ToMany
注释中删除该属性。
But note that in most cases a Set<Child>
is more appropriate than List<Child>
, so unless you really need a List
- go for Set
但请注意,在大多数情况下 aSet<Child>
比 更合适List<Child>
,因此除非您确实需要 a List
- 去Set
But remind that with using sets you won'teliminate the underlaying Cartesian Productas described by Vlad Mihalcea in his answer!
但请注意,使用集合不会消除Vlad Mihalcea 在他的回答中描述的底层笛卡尔积!
回答by Ahmad Zyoud
Simply change from List
type to Set
type.
只需从List
类型更改为Set
类型。
But remind that you won'teliminate the underlaying Cartesian Productas described by Vlad Mihalcea in his answer!
但请注意,您不会消除Vlad Mihalcea 在他的回答中所描述的底层笛卡尔积!
回答by Dave Richardson
回答by Christian Müller
I found a good Blog post about the behaviour of Hibernate in this kind of object mappings: http://blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html
我找到了一篇关于 Hibernate 在这种对象映射中的行为的很好的博客文章:http: //blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html
回答by Javier
After trying with every single option describe in this posts and others, I came to the conclusion that the the fix is a follows.
在尝试了这篇文章和其他文章中描述的每个选项后,我得出的结论是修复如下。
In every XToMany place @XXXToMany(mappedBy="parent", fetch=FetchType.EAGER)
and intermediately after
在每个 XToMany 地方 @XXXToMany(mappedBy="parent", fetch=FetchType.EAGER)
和中间之后
@Fetch(value = FetchMode.SUBSELECT)
This worked for me
这对我有用
回答by Prateek Singh
To fix it simply take Set
in place of List
for your nested object.
要修复它,只需Set
代替List
您的嵌套对象即可。
@OneToMany
Set<Your_object> objectList;
and don't forget to use fetch=FetchType.EAGER
并且不要忘记使用 fetch=FetchType.EAGER
it will work.
它会起作用。
There is one more concept CollectionId
in Hibernate if you want to stick with list only.
CollectionId
如果您只想坚持使用列表,那么 Hibernate 中还有一个概念。
But remind that you won'teliminate the underlaying Cartesian Productas described by Vlad Mihalcea in his answer!
但请注意,您不会消除Vlad Mihalcea 在他的回答中所描述的底层笛卡尔积!
回答by Felipe Cadena
When you have too complex objects with saveral collection could not be good idea to have all of them with EAGER fetchType, better use LAZY and when you really need to load the collections use: Hibernate.initialize(parent.child)
to fetch the data.
当你有太复杂的对象和保存集合时,让所有对象都带有 EAGER fetchType 并不是一个好主意,最好使用 LAZY,当你真的需要加载集合时,使用:Hibernate.initialize(parent.child)
来获取数据。
回答by Massimo
you can keep booth EAGER lists in JPA and add to at least one of them the JPA annotation @OrderColumn(with obviously the name of a field to be ordered). No need of specific hibernate annotations. But keep in mind it could create empty elements in the list if the chosen field does not have values starting from 0
您可以在 JPA 中保留展位 EAGER 列表,并至少向其中一个添加 JPA 注释@OrderColumn(显然是要订购的字段的名称)。不需要特定的休眠注释。但请记住,如果所选字段没有从 0 开始的值,它可能会在列表中创建空元素
[...]
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@OrderColumn(name="orderIndex")
private List<Child> children;
[...]
in Children then you should add the orderIndex field
在 Children 然后你应该添加 orderIndex 字段
回答by leee41
You could use a new annotation to solve this:
您可以使用新的注释来解决这个问题:
@XXXToXXX(targetEntity = XXXX.class, fetch = FetchType.LAZY)
In fact, fetch's default value is FetchType.LAZY too.
事实上,fetch 的默认值也是 FetchType.LAZY。
回答by Mike Dudley
We tried Setinstead of Listand it is a nightmare: when you add two new objects, equals() and hashCode() fail to distinguish both of them ! Because they don't have any id.
我们尝试了Set而不是List,这是一场噩梦:当您添加两个新对象时,equals() 和hashCode() 无法区分它们!因为他们没有身。
typical tools like Eclipse generate that kind of code from Database tables:
像 Eclipse 这样的典型工具从数据库表生成那种代码:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
You may also read this articlethat explains properly how messed up JPA/Hibernate is. After reading this, I think this is the last time I use any ORM in my life.
您还可以阅读这篇文章,它正确地解释了 JPA/Hibernate 是多么混乱。读完这篇,我想这是我这辈子最后一次使用任何 ORM。
I've also encounter Domain Driven Design guys that basically say ORM are a terrible thing.
我也遇到过领域驱动设计的人,他们基本上说 ORM 是一件可怕的事情。