Hibernate的Entit Manager数据值重复的问题

问题描述:
当使用Hibernate的Anotation来定义一个复杂对象时,有可能需要关联别的表,当该对象与关联的表的关系为一对多,或多对多时,即 Entity的属性值为数组或者集合,且上面加有 @org.hibernate.annotations.CollectionOfElements @OneToMany或者@ManyToMany标签时,Hibernate会把该属性当做一个包来处理, 示例代码:
@OneToMany(mappedBy="parent",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
 List<Child1> child1s = new LinkedList<Child1>(); @OneToMany(mappedBy="parent",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
 List<Child2> child2s= new LinkedList<Child2>(); 

Hibernate在解析这个Entity的时候,可能会出现一些意外情况,有时会抛出“HibernateException: cannot simultaneously fetch multiple bags ”这样的异常,有时会出现数据项重复的情况,比方说,有如下的一个叫Parent的Entity, 它有2个属性Child1和Child2,数据库中的表结构如下:
Hibernate的Entit Manager数据值重复的问题_第1张图片
Hibernate的Entit Manager数据值重复的问题_第2张图片
Hibernate的Entit Manager数据值重复的问题_第3张图片
当Hibernate在解析ID为122 的Parent 的时候, 会首先把与该Entity相关的数据全部获取出来,形成如下的表结构:
Hibernate的Entit Manager数据值重复的问题_第4张图片

从上表中标红的字体,可以发现,虽然CHILD2表里面只有一行数据,但是却在数据中重复出现了2次,这就导致在child2s这个集合属性值里面有2条一模一样的数据。

解决方法:
1、为属性值添加Anotation @IndexColumn(name="child2_id") 以指定属性值关联表的unique ID,当Hibernate解析该属性值,会先查看是否已经加载过相同的属性值,这样就避免了相同数据的重复加载。

2、把属性值的类型修改为Set这样,就当Hibernate把数据添加到属性值的时候就自动去重了。

你可能感兴趣的:(java,Hibernate)