博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么Hibernate不允许同时抓取两个和两个以上的平行bag集合
阅读量:7223 次
发布时间:2019-06-29

本文共 1107 字,大约阅读时间需要 3 分钟。

hot3.png

在hibernate中, 如果试图同时抓取两个或两个以上平行的bag集合,会抛出这个异常:org.hibernate.HibernateException: cannot simultaneously fetch multiple bags。对于这种情况,Hibernate文档给出的解释是: The resultset of a product can’t be converted into bag collections, because Hibernate can’t know which rows contain duplicates that are valid (bags allow duplicates) and which aren’t.

这里具体再解释一下。我们知道:抓取平行集合会产生笛卡尔积, 是笛卡尔积就会有重复记录。这对于允许有重复记录的bag集合有麻烦了,因为hibernate无法区分(确实地说是bag集合无法区分)这些重复的记录是因笛卡尔积而产生的(如果是这种记录,在封装对象是就要排除出去)还是真正的记录。注意:Hibernate不会通过比较ID来确定它们是否重复的,因为集合内的元素不一定都有ID的,比如值对象。 这也正是idbag为什么不存在这个问题的原因所在!在这种情况下,如果hibernate不抛出异常,就只能向bag集合中添加这些元素,而bag集合是允许重复记录的,这样,bag集合就会照单全收。对于set集合就不会出现这种情况,因为在添加对象时,它会检查是否已经加过这个元素了,重复的元素就会被排除出去。从这里我们也应该注意到:对于Set集合内的元素,重写hashCode和equals方法是多么地重要!

举个例子吧:对象A有一个B的bag集合和一个C的bag集合。假定a1有一个b1和b2组成的B集合,和一个c1组成的C集合,那么当使用join平行抓取B和C集合时,生成的结果集是:

a1,b1,c1

a1,b2,c1

现在,当hibernate将这个结果集封装成a1对象时,对于a1的C集合,hibernate首先将第一条记录中的c1加到集合里,当遇到第二条记录的c1时,因为C集体是一个bag集合,它不做检查就会接受这个c1.这就是问题的所在。即使这两个c1所有值全都是一样的,也包括ID,但是将之封装为对象加入C集合时,它是不做检查的。如果是set集合,它会检查它们的hashCode和equals方法,通过比较主键或业务主键,来确定它们是不是重复的。

转载于:https://my.oschina.net/pangzhuzhu/blog/327132

你可能感兴趣的文章
ZedGraph源码学习(三)
查看>>
EasyVS 0.4 发布 -- 新增4项功能
查看>>
走进小作坊(十一)----移动web实现指南
查看>>
java + memcached安装
查看>>
十道智力题(三)
查看>>
Ubuntu下查看linux版本,内核版本,系统位数,gcc版本
查看>>
\n 与 \r 在记事本中的内容表现方式 原创
查看>>
分布式任务&分布式锁
查看>>
利用百度API Store接口进行火车票查询
查看>>
关于offset()的理解
查看>>
【踩坑记】从HybridApp到ReactNative
查看>>
maven全局配置文件settings.xml详解
查看>>
23种设计模式之状态模式(State)
查看>>
【Android小项目】找不同,改编自"寻找房祖名"的一款开源小应用。
查看>>
jquery文档操作
查看>>
CSS reset
查看>>
操作系统之分页分段介绍
查看>>
004PHP基础知识——数据类型(一)
查看>>
Linux查看哪些进程用了Swap分区
查看>>
在canvas上面绘制图片--drawImage实例
查看>>