TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常: * F T5 p! w0 _1 R* s
Illegal attempt to associate a collection with two open sessions - c& O9 N9 E0 M- D, [! d
1.如以下找到的资料之一: ; F" v1 {& O- L) e" { @5 _
错误信息: 3 _2 P7 Z) n3 b0 W$ }5 @+ Z: H6 q
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions;
9 w9 U8 ?8 @ @9 P @' ^错误原因: ! F7 I( F. g* |% e, x9 @ ^' ]
1. 一个Action在两个线程中同时运行,造成并发。 5 N3 C% l$ I8 V) a7 _& N
解决方法: ) Y$ R( A# }7 o4 ?" O3 N: N
1. 阻止重复提交。可以利用struts Token机制。
- ?7 F/ l2 Y0 i6 w但是还是不能解决我的问题。
( R2 z: m7 o+ n: I2 ]+ s! G1 \2.经常debug 测试 终于发现了一个问题:
+ Q+ [8 l. [& l+ X 原来属性重名了
- v) }3 F/ k; K3 A+ S 我在Action中已经注入了实体类 ; n) |; q% z" A* [/ A
private Mission mission; 3 u$ l0 B ?4 y8 P! u; P, l& n
在下面某个内部类方法中也重名的定义
( ^4 w8 y- J; ~' e0 N9 d2 m/ l; xMission mission = misList.get(0);
4 ^* X; a ]; ?2 e1 P8 \& @$ s' J并且他们都被调用了同一方法
0 d" P" f- [9 m7 @; G( imissionBussiness.addData(mis); % U6 f* {8 `% @* o7 d* S. S
处理结果:改掉其中的一个属性名,错误仍然存在。 ! x( {4 p8 F8 ~8 E0 O
7 e- Y% h- g$ a3 h3 S$ z3.找到资料 :
3 j) O, f, D) Z7 [ 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
1 j& P" J' z. }$ h4.最后终于找到一个可以解决我问题的方案:
$ b* ~( H3 m- W/ p' {3 N( X- x/ V 使用hibenate的merge方法代替save、update等方法。 0 k8 p) n8 L5 k0 @
merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
( s! A3 M8 u& V+ B2 I5 {6 S: h: v, t( B
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法 7 i" {- Q- y/ l; l3 k" x& k
" I4 k' z7 A9 i9 G: o
将此方法:public boolean addData(Object data) throws Exception { ' L% F$ a9 O/ |! j* |' `* R
this.getHibernateTemplate().save(data); * Y( u+ m: ]: ~/ ?. ^* |! B8 p. V
return true; ( y6 b$ W V" h! E) t# r
} ' w; E- v4 R& }; \
改为:
) u1 j% {* W8 Tpublic boolean addData(Object data) throws Exception {
# t8 K% k* D! ]* M this.getHibernateTemplate().merge(data);
0 w0 C, H/ ?% F# y1 c2 L return true;
1 W( X4 W5 H# c: e1 {" N9 v }
$ t8 H. I/ l# ~$ v+ X将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
5 a0 e- u5 B: C: X* h8 D: _9 o* }: Q; h
将此方法:public void update(Object data) throws Exception {
6 A% o$ |: x2 V' s/ I2 Z super.getHibernateTemplate().update(data);
- s& v$ l1 }7 K( [" p } ( P0 J) `) p, C/ m
改为:public void update(Object data) throws Exception { $ C& A8 m* Q E! J
super.getHibernateTemplate().merge(data); ! E: z G! @4 m n; C
}
% l' m9 a; j$ C
7 v" P9 C( d2 v
1 g. Z" ~( X2 [( H9 b |
|