hibernate不能同时取多个行李

Hibernate在SessionFactory创build期间抛出这个exception:

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

这是我的testing用例:

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

这个问题怎么样? 我能做什么?


编辑

好的,我的问题是另一个“父母”实体是在我的父母,我真正的行为是这样的:

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不喜欢两个集合与FetchType.EAGER ,但这似乎是一个错误,我不做不寻常的事情…

ParentFetchType.EAGER删除FetchType.EAGER可以解决这个问题,但是我需要它,所以真正的解决scheme是使用@LazyCollection(LazyCollectionOption.FALSE)而不是FetchType (感谢Bozho的解决scheme)。

我认为更新版本的hibernate(支持JPA 2.0)应该能够处理这个问题。 但除此之外,您可以通过使用以下注释来收集字段:

 @LazyCollection(LazyCollectionOption.FALSE) 

请记住从@*ToMany注释中删除fetchType属性。

但是请注意,在大多数情况下, Set<Child>List<Child>更合适,所以除非你真的需要List – 去Set

只需从Listtypes更改为Settypes。

或者,在您的代码中添加一个Hibernate特有的@Fetch注释:

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER) @Fetch(value = FetchMode.SUBSELECT) private List<Child> childs; 

这应该解决与Hibernate bug HHH-1718有关的问题

在尝试用这个post和其他人描述的每一个选项后,我得出的结论是修复如下。

在每个XToMany的地方@ XXXToMany(mappedBy="parent", fetch=FetchType.EAGER)以及之后

 @Fetch(value = FetchMode.SUBSELECT) 

这对我有效

为了解决这个问题,只需要为你的嵌套对象取代List

 @OneToMany Set<Your_object> objectList; 

不要忘记使用fetch=FetchType.EAGER

它会工作。

如果你想只保留列表,在Hibernate中还有一个概念CollectionId

我在这种对象映射中发现了一篇关于Hibernate行为的博客文章: http : //blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html

您可以在JPA中保留EAGER列表,并在其中至less添加一个JPA批注@OrderColumn (明显是要订购的字段的名称)。 不需要特定的hibernate注释。 但请记住,如果所选字段的值不是从0开始,则可以在列表中创build空元素

  [...] @OneToMany(mappedBy="parent", fetch=FetchType.EAGER) @OrderColumn(name="orderIndex") private List<Child> children; [...] 

在儿童那么你应该添加orderIndex字段

当你有太复杂的对象时,使用saveral集合并不是一个好主意,用EAGER的fetchType来完成所有的对象,最好使用LAZY,而当你确实需要加载集合的时候,使用: Hibernate.initialize(parent.child)来获取数据。

你可以使用一个新的注解来解决这个问题:

 @XXXToXXX(targetEntity = XXXX.class, fetch = FetchType.LAZY) 

实际上,获取的默认值也是FetchType.LAZY。