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
,但这似乎是一个错误,我不做不寻常的事情…
从Parent
或FetchType.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
只需从List
types更改为Set
types。
或者,在您的代码中添加一个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。