文档章节

为什么Hibernate不允许同时抓取两个和两个以上的平行bag集合

猪刚烈
 猪刚烈
发布于 2014/10/12 11:47
字数 660
阅读 9
收藏 0

在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方法,通过比较主键或业务主键,来确定它们是不是重复的。

本文转载自:http://blog.csdn.net/bluishglc/article/details/5579132

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
hibernate N+1问题

Hibernate N+1 问题及解决办法 问题出现的原因: Hibernate 中常会用到 set , bag 等集合表示 1 对多的关系,在获取实体的时候就能根据关系将关联的对象或者对象集取出,还可以设定 cacade...

毅屺
2016/03/20
77
0
Hibernate缓存与集合性能分析

Hibernate作为一个应用级的数据访问层封装,只能在其作用范围内保持cache中数据的有效性,如果系统与第三方系统共享数据库的情况下,Hibernate的Cache机制可能失效。 Hibernate在本地JVM中维...

疯子船长
2015/10/26
0
0
EJB持久层cannot simultaneously fetch multiple bags异常的解决

病理特征:Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags, 堆栈信息:org.springframework.beans.factory.BeanCreationException: Error crea......

曹_翔
2011/01/04
0
0
[Hibernate]一对多和多对一中各个参数的说明

many-to-one节点有以下属性(摘自Hibernate文档): 序号 属性 说明 1 name 属性名 2 column (可选): 外间字段名。它也可以通过嵌套的 <column> 元素指定。 3 class (可选 - 默认是通过反射得...

彪大大
2016/01/22
65
0
cannot simultaneously fetch multiple bags 异常的解决办法

异常信息如下: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags ...... 问题是什么时候出现的呢? 当一个实体对象中包含多于一个non-lazy获取...

liangtee
2012/10/09
0
1

没有更多内容

加载失败,请刷新页面

加载更多

腾讯投资最高1.75亿美元正式进军菲律宾移动支付市场

菲律宾长途电话公司(PLDT)公司今日宣布,中国互联网巨头腾讯和私募股权公司KKR将获得该公司旗下金融科技公司Voyager Innovations的少数股权。 PLDT在一份声明中称:“腾讯和KKR最多将分别收...

linuxCool
19分钟前
2
0
正则介绍及grep/egrep用法

10月16日任务 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 扩展 把一个目录下,过滤所有*.php文档中含有eval的行 grep -r --include="*.php" 'eval' /data 正则介绍 正则就是一串有规律的字符...

hhpuppy
30分钟前
1
0
J2Cache 中使用 Lettuce 替代 Jedis 管理 Redis 连接

一直以来 J2Cache 都是使用 Jedis 连接 Redis 服务的。Jedis 是一个很老牌的 Redis 的 Java 开发包,使用很稳定,作者维护很勤勉,社区上能搜到的文章也非常非常多。算是使用范围最广的 Redi...

红薯
今天
12
0
一个可能的NEO链上安全随机数解决方案

0x00 困境 链上安全随机数生成应该算是一个比较蛋疼的问题,哪怕你的系统再牛逼,合约程序困在小小的虚拟机里,哪怕天大的本事也施展不开。 更悲催的是,交易执行的时候,是在每一个节点都执...

暖冰
今天
1
0
【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部