Hibernate throws this exception during SessionFactory creation:
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
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 AntoherParent anotherParent;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
private List<Child> children;
}
AnotherParent.java
@Entity
public AntoherParent {
@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...
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 Bozho for the solution).
We tried Set instead of List and 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.
typical tools like Eclipse generate that kind of code from Database tables:
You may also read this article that 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.
I've also encounter Domain Driven Design guys that basically say ORM are a terrible thing.
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.To fix it simply take
Set
in place ofList
for your nested object.and don't forget to use
fetch=FetchType.EAGER
it will work.
There is one more concept
CollectionId
in Hibernate if you want to stick with list only.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
You could use a new annotation to solve this:
In fact, fetch's default value is FetchType.LAZY too.
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:
Remember to remove the
fetchType
attribute from the@*ToMany
annotation.But note that in most cases a
Set<Child>
is more appropriate thanList<Child>
, so unless you really need aList
- go forSet