关于Hibernate中fatch=eager的bag集合(一个java List)使用Criteria查询出现重复记录的问题
2010-05-05 15:03
1091 查看
关于这个问题在JPwH一书的13.2.3一节中做了详细的描述!
例子:ForumGroup和Forum
由于ForumGroup的forums被配制为eager fetch,也就是说在加载ForumGroup时,会同一并把它的所有Forum一起加载出来,这个过程是通过left out join来实现的。下面是hibernate打出的sql.
select
this_.id as id3_1_,
this_.creationTime as creation2_3_1_,
this_.description as descript3_3_1_,
this_.modifiedTime as modified4_3_1_,
this_.name as name3_1_,
forums2_.groupId as groupId3_,
forums2_.id as id3_,
forums2_.id as id2_0_,
forums2_.creationTime as creation2_2_0_,
forums2_.description as descript3_2_0_,
forums2_.groupId as groupId2_0_,
forums2_.modifiedTime as modified4_2_0_,
forums2_.name as name2_0_
from
ForumGroup this_
left outer join
Forum forums2_
on this_.id=forums2_.groupId
假定有1个ForumGroup,它有3个Forum,上面的sql会生成3条记录。那么Hibernate是如何封装这3条数据的呢?从实际的代码运行结果中可以看到:首先,Hibernate确实只生成了一个ForumGroup的实例和3个Forum的实例。但是如果你使用loadAllForumGroup时,会返回3个ForumGroup的引用,指向同一个ForumGroup的实例!
如果把ForumGroup的forums被配制为lazy fetch,会解决这个问题。但这也只是回避了这个问题!
正确的解决方法是什么呢?
如果想过滤join和fetch中的重复对象,有两种方法:
1.将续集里封装成set.比如:Set noDupes = new LinkedHashSet(resultList))
2.使用DISTINCT。比如:select distinct i from Item i join fetch i.bids
另外一个问题是:
在用JPA进行注释时,如果一个实体里要映射多个集合实体时,我们不能把两个集合的的FetchType设置为EAGER,此时只能设置为LAZY,否则会报:cannot simultaneously fetch multiple bags。或者我们也可以借助:@IndexColumn (加了它就不再是bag集合了,而是list集合了)。也就是说,hibernate不允许一次抓取多个bag.
例子:ForumGroup和Forum
public class ForumGroup { @OneToMany(fetch=FetchType.EAGER,mappedBy="group") private List<Forum> forums = new ArrayList<Forum>(); } public class Forum { @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="groupId",nullable=false) @org.hibernate.annotations.ForeignKey(name="fk_Forum_groupId_ForumGroup") private ForumGroup group; }
由于ForumGroup的forums被配制为eager fetch,也就是说在加载ForumGroup时,会同一并把它的所有Forum一起加载出来,这个过程是通过left out join来实现的。下面是hibernate打出的sql.
select
this_.id as id3_1_,
this_.creationTime as creation2_3_1_,
this_.description as descript3_3_1_,
this_.modifiedTime as modified4_3_1_,
this_.name as name3_1_,
forums2_.groupId as groupId3_,
forums2_.id as id3_,
forums2_.id as id2_0_,
forums2_.creationTime as creation2_2_0_,
forums2_.description as descript3_2_0_,
forums2_.groupId as groupId2_0_,
forums2_.modifiedTime as modified4_2_0_,
forums2_.name as name2_0_
from
ForumGroup this_
left outer join
Forum forums2_
on this_.id=forums2_.groupId
假定有1个ForumGroup,它有3个Forum,上面的sql会生成3条记录。那么Hibernate是如何封装这3条数据的呢?从实际的代码运行结果中可以看到:首先,Hibernate确实只生成了一个ForumGroup的实例和3个Forum的实例。但是如果你使用loadAllForumGroup时,会返回3个ForumGroup的引用,指向同一个ForumGroup的实例!
如果把ForumGroup的forums被配制为lazy fetch,会解决这个问题。但这也只是回避了这个问题!
正确的解决方法是什么呢?
如果想过滤join和fetch中的重复对象,有两种方法:
1.将续集里封装成set.比如:Set noDupes = new LinkedHashSet(resultList))
2.使用DISTINCT。比如:select distinct i from Item i join fetch i.bids
另外一个问题是:
在用JPA进行注释时,如果一个实体里要映射多个集合实体时,我们不能把两个集合的的FetchType设置为EAGER,此时只能设置为LAZY,否则会报:cannot simultaneously fetch multiple bags。或者我们也可以借助:@IndexColumn (加了它就不再是bag集合了,而是list集合了)。也就是说,hibernate不允许一次抓取多个bag.
相关文章推荐
- this.getHibernateTemplate().find()出现查询到的记录重复的问题
- 关于Hibernate查询出现重复数据的问题和解决方案
- Java 关于使用Arrays.asList()数组转集合的问题
- hibernate使用list映射,查询出来的list集合包含多个null记录
- 记录一个java.util.logging.Logger 使用中关于时间格式的问题
- 关于java中的List集合的排序问题/Collections.sort()的使用(转)
- 求助Hibernate问题(我使用Criteria 查询数据库表时,当客户端调用到第3次就出现问题 )
- 关于在使用Hibernate时出现javassist.bytecode.DuplicateMemberException的问题
- 执行SQL语句时出现问题操作必须使用一个可更新的查询错误的解决方法
- Hibernate Criteria 多层次查询关联问题 HibernateJava
- 关于 hibernate 逻辑删除 默认查询过滤条件问题(java set 条件)
- Hibernate中使用Criteria查询及注解——(Dept.java)
- Hibernate中关于多表连接查询hql 和 sql 返回值集合中对象问题
- Hibernate 多表关联映射- Hibernate中使用的集合类型(set,list,array,bag,map)
- 使用Hibernate criteria进行分页查询时,如何实现一次查询取得总记录数和分页后结果集
- Hibernate 多表关联映射- Hibernate中使用的集合类型(set,list,array,bag,map)
- 2017-6-14 关于使用history.go的问题!配合原生应用嵌入H5页面(只有一个webview的的单页应用)返回历史列表记录的问题
- myeclipse里工程的jdk使用的1.7版本,其中java compiler最高只能选到1.6的问题(在maven工程中出现的问题) -- 记录
- 解决Hibernate使用HQL查询出现is not mapped问题
- 使用Criteria查询级联表时出现的问题及解决