在说解决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;
- }
转自:http://dyldragon.iteye.com/blog/788385
相关推荐
Differential absorption lidar (DIAL) has ... In this paper, a simple and accurate algorithm is presented for simultaneously detecting and estimating multiple vapor materials with multiple-wavelength DI
We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license ...
"Modeling and Simultaneously Removing Bias via Adversarial Neural Networks"这篇论文提出了一种新颖的方法,通过对抗性神经网络(Adversarial Neural Network, ANN)来同时建模并消除这种偏差。 传统的解决偏差...
本文旨在解决Simultaneously Wireless Information and Power Transfer(SWIPT)接收机资源分配策略中不考虑未来时刻网络性能的问题。为此,提出了基于神经网络的SWIPT接收机资源分配策略。该策略首先从能量和时间的...
在高分子材料的大型注射成型制品制造中,难以避免材料的机械性能与流动性之间的矛盾。由于大型制品往往需要材料具有良好的流动性来实现成型,但是这又会导致其力学性能下降。为解决这一问题,文章介绍了一种新开发的...
高密度聚乙烯(HDPE)作为一种常见的工程塑料,其优异的化学稳定性、良好的加工性以及较低的生产成本使其在工业应用中非常广泛。然而,传统注射成型工艺(CIM)在实现聚合物材料的良好流动性和机械性能方面存在挑战...
文章详细介绍了当电常数和磁导率同时取负值时可能引起的一些物理现象和理论推导,以及在现实物理世界中尚未发现有此类物质,但给出了一些理论上的预测和寻找此类物质的方向。 在电磁学中,电常数(ε)和磁导率(μ...
This paper combines workspace models with optimization techniques to simultaneously address wholearm collision avoidance, joint limits and camera field of view (FOV) limits for vision-based motion ...
此外,论文还考虑了最小化移动充电器的充电旅程长度问题,也就是最小化充电器的旅行距离,假定移动充电器拥有足够的能量来支持所有请求的传感器充电以及它自身的移动。如果移动充电器在其充电旅程上的能量消耗可以...
View Assessment Result: Multiple-Choice Quiz 2 Your performance was as follows: 1. The degree of a table is the number of _____ in the table. (a) keys (b) columns (c) rows (d) ...
may be associated with multiple labels simultaneously. A key difference between multi-label learning and traditional binary or multi-class learning is that the labels in multi-label learning are not ...
TEmailServer is a built-in SMTP server that can simultaneously validate or verify email addresses and send multiple email messages. This component is ideal for building email address validator or ...
破解版 TEmailServer is a built-in SMTP server that can simultaneously validate or verify email addresses and send multiple email messages. TEmailServer is an ideal component for building email address...
本文讨论的是一类三维逆几何问题,即形状识别问题,主要关注的是同时估计复合域中两个界面配置的问题。复合域指的是由三个不同区域构成的区域。在研究中,使用了共轭梯度法(Conjugate Gradient Method, CGM)和商业...
You can communicate with multiple ports simultaneously. See the Quick Start Guide. MBAXP Technical Facts and Features: RTU Mode. ASCII Mode. Modbus TCP/IP. Multi-threaded for high data throughput. ...
If more than 8 analog input channels are required, multiple cards can be synchronized through the Device-to-Device Bus to support more AI channels simultaneously sampling. The PCI-1706U has two 12-...
In order to track multiple particles within a whole cell simultaneously, a parallel tracking approach with large depth of field was put forward. It was based on distorted grating and dual-objective ...