Hibernate抓取策略以及如何避免cannot simultaneously fetch multiple bags异常
来源:互联网 发布:淘宝达人后如何直播 编辑:程序博客网 时间:2024/05/22 00:22
Hibernate抓取策略以及如何避免cannot simultaneously fetch multiple bags异常
- 博客分类:
- hibernate
在说解决cannot simultaneously fetch multiple bags异常之前,我先说下抓取策略
注解@Fetch(FetchMode.?)抓取策略有三种
1、FetchMode.JOIN(默认的抓取策略),采用外连接的形式,left outer join ... on
2、FetchMode.SELECT 会另外发送一条sql语句加载当前对象的关联实体
3、FetchMode.SUBSELECT 会另外发送一条select语句抓取前面查询到的所有实体对象的关联实体
通过Hibernate输出的SQL日志看成,个人感觉2、3的差别不是太大 ,都是另起select语句查询与当前某个实体相关联的其他实体。
下面是我写的一个简单DEMO,主要来验证抓取策略和异常的处理方法
表结构
人员表 tb_person
+-------------+
| Field |
+-------------+
| person_id |
| person_age |
| person_name |
+-------------+
一个人员可以有多个邮箱,邮箱表,人-邮箱是一对多的关系tb_person_email
+-----------+
| Field |
+-----------+
| id |
| person_id |
| address |
+-----------+
事件表,一个人可以有多个事件,一个事件也可有多个人处理,是多对多关系tb_event,tb_person_event
+-------------+
| Field |
+-------------+
| event_id |
| event_title |
| event_date |
+-------------+
+-----------+
| Field |
+-----------+
| event_id |
| person_id |
+-----------+
要执行的方法是:搜索人,以及相关的事件和邮件。
person.java
第一种写法,采用默认join抓取策略,进行强制抓取person所有关联对象的方式
- @ManyToMany(fetch=FetchType.EAGER)
- @JoinTable(name = "TB_PERSON_EVENT", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "EVENT_ID")})
- public List<Event> getEvents() {
- return events;
- }
- @OneToMany(fetch=FetchType.EAGER)
- @JoinTable(name = "TB_PERSON_EMAIL", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "ID")})
- ublic List<Email> getEmails() {
- return emails;
如果这样写的情况下, 就会报cannot simultaneously fetch multiple bags异常,从SQL日志分析,hibernate是这样执行的
- select *
- from TB_PERSON tp left outer join TB_PERSON_EMAIL tpe1 on tp.person_id = tpe1.person_id
- left outer join TB_PERSON_EMAIL tpe2 on tpe1.id = tpe2.id
- left outer join TB_PERSON_EVENT tpet on tp.person_id = tpet.person_id
- left outer join TB_EVENT te on tpet.event_id = te.event_id
- where tp.person_id = 2;
输出的记过,就会出现两个同样的email实体列,所以就报上述异常。
如果要避免这个异常,我在网上搜了许多资料都是说把fetch=FetchType.LAZY
变成懒加载模式,或者把List修改成Set集合,这两种我验证过了,是可以行的通的,但是如果不想采取这种两种办法,
怎么办。
其实还有一种,是看springside得到的一种方法,代码修改如下
- @ManyToMany(fetch=FetchType.EAGER)
- @JoinTable(name = "TB_PERSON_EVENT", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "EVENT_ID")})
- @Fetch(FetchMode.SUBSELECT)
- public List<Event> getEvents() {
- return events;
- }
- @OneToMany(fetch=FetchType.EAGER)
- @JoinTable(name = "TB_PERSON_EMAIL", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "ID")})
- @Fetch(FetchMode.SUBSELECT)
- public List<Email> getEmails() {
- return emails;
- }
这种方法就是在不修改原结构注释的情况下,可以修改一下抓取策略,分开select实体,这样就不会出现重复列现象。
个人感觉还是不错的方法,打算就用它了。
另外就是个人并不是太喜欢全抓取,密密麻麻一大堆的SQL打印的控制台上,排查SQL都麻烦,所以最终修改版,个人比较喜欢的注释方法:
- @ManyToMany(fetch=FetchType.LAZY)
- @JoinTable(name = "TB_PERSON_EVENT", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "EVENT_ID")})
- @Fetch(FetchMode.SUBSELECT)
- public List<Event> getEvents() {
- return events;
- }
- @OneToMany(fetch=FetchType.LAZY)
- @JoinTable(name = "TB_PERSON_EMAIL", joinColumns = {@JoinColumn(name = "PERSON_ID")},
- inverseJoinColumns = {@JoinColumn(name = "ID")})
- @Fetch(FetchMode.SUBSELECT)
- public List<Email> getEmails() {
- return emails;
- }
收工,就写到这里了,该吃饭喽。
- 2010-10-19 12:44
- 浏览 7234
- 评论(6)
- 收藏
- 分类:企业架构
- 相关推荐
- Hibernate抓取策略以及如何避免cannot simultaneously fetch multiple bags异常
- Hibernate抓取策略以及如何避免cannot simultaneously fetch multiple bags异常
- Hibernate - cannot simultaneously fetch multiple bags 异常
- Hibernate:cannot simultaneously fetch multiple bags 解决方案
- cannot simultaneously fetch multiple bags
- cannot simultaneously fetch multiple bags
- cannot simultaneously fetch multiple bags
- cannot simultaneously fetch multiple bags
- JPA的cannot simultaneously fetch multiple bags异常的解决
- cannot simultaneously fetch multiple bags异常的解决
- JPA的cannot simultaneously fetch multiple bags异常的解决
- cannot simultaneously fetch multiple bags 异常的解决办法
- PA的cannot simultaneously fetch multiple bags异常的解决
- Hibernate: cannot simultaneously fetch multiple bags 问题的解决办法
- Hibernate中:cannot simultaneously fetch multiple bags的问题
- Hibernate: cannot simultaneously fetch multiple bags 问题的解决办法
- Hibernate could not inittialize proxy-no Session 以及cannot simultaneously fetch multiple bags
- cannot simultaneously fetch multiple bags 解决方式
- 黑马程序员----Java基础之IO包中其它类
- openOffice和SWFTools 在线浏览
- 支付功能实现的大致思路
- ABAP根据输入的表名动态生成上传EXCEL数据的代码
- 循环广告位组件的实现
- Hibernate抓取策略以及如何避免cannot simultaneously fetch multiple bags异常
- MFC 设置按钮背景,点击后切换背景(不是按下时和松开时切换)
- oracle 数据库表的列名修改
- 如何正确的使用SharedPreferences?
- matlab中size()函数的用法
- Linux解压缩命令大全
- 有关国内的流氓软件和强制安装软件(网站黑名单一览表)
- 画数组的直方图
- lightoj - 1032 Fast Bit Calculations (数位dp)总结
评论
修改为
其他内容保持不变,这样测试下来没有出现问题。
无需,测博主代码,表示正常无压力~!
遇到情况,加上这东西也不报错了
修改为
其他内容保持不变,这样测试下来没有出现问题。