TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
/ |% ^, n6 n+ J& p+ ^* H& ~/ Q lIllegal attempt to associate a collection with two open sessions 4 G6 }1 Y S% C* Z, }5 o: a
1.如以下找到的资料之一: ' Q" Y7 Z4 ?5 G+ v6 o ~! ?
错误信息: + T" h" _+ q9 j! v. |6 Y4 G# N" }; y) e `
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions;
3 p. J" Q G" p5 ^: |3 a错误原因:
* |/ b& y2 Z7 x) Z7 [1. 一个Action在两个线程中同时运行,造成并发。 , {% x0 w( S6 n. ]4 T' d) P- N; n; v
解决方法: 4 |$ ?3 n( j2 I8 O, @0 r
1. 阻止重复提交。可以利用struts Token机制。
; x1 S/ A2 ^4 a! @/ O但是还是不能解决我的问题。 9 c4 Y, s7 ^3 l2 ?/ w" z; p7 E- p
2.经常debug 测试 终于发现了一个问题:
7 y: k$ T& O7 @. Q D0 q/ f, ` 原来属性重名了
4 @; X1 @* X( t% x6 Z. y; M' F 我在Action中已经注入了实体类
6 j$ I8 I+ `! q5 bprivate Mission mission; 0 ?2 k: k! W+ f. |0 e# h& I
在下面某个内部类方法中也重名的定义 % {2 W# h) k, Z% H1 I# m8 R
Mission mission = misList.get(0);
8 p1 G9 I/ z0 I, `+ X+ m并且他们都被调用了同一方法
8 I) o4 E; B* B9 ^missionBussiness.addData(mis); % p- u* i, E l5 _) ~& a& W
处理结果:改掉其中的一个属性名,错误仍然存在。
! p1 U2 m. }3 x3 F( h& b+ t; {: g2 _$ n$ [$ Q
3.找到资料 : 8 T) E* ]- ] f# d4 t) P
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
7 J0 [& j2 V f1 n# u5 E3 [4.最后终于找到一个可以解决我问题的方案:
, P1 g$ e& H) z+ b. b ^$ \ 使用hibenate的merge方法代替save、update等方法。 7 R3 r% E& k. [! q2 }) B/ o0 U" r
merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge 2 e+ u. D5 T; e% @) B
: V( f% E! a, \- C% R将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法 9 C, e/ W7 a/ I( U
! k' i5 @' ]" O- c# ]( c; J( q
将此方法:public boolean addData(Object data) throws Exception { % j- [0 i; ~8 t) j& P- d; F
this.getHibernateTemplate().save(data);
4 F% G( L3 g. k2 ^ Y1 x& K return true; . [8 W @1 `$ B* _' A ~& @
}
" \# u I( l) L5 k/ g4 W# W% k改为:
& }' j( E# Y7 z$ Gpublic boolean addData(Object data) throws Exception {
; ]$ |2 }* E9 y this.getHibernateTemplate().merge(data); # p4 F! [$ R1 y: @. |
return true; ) q( W$ C/ l1 F" B
}
9 Q8 L( i/ a: M$ }' S将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 : |# `* S8 u' K4 A/ M9 j8 n
, a. x+ M& P" _2 O- y( Y将此方法:public void update(Object data) throws Exception {
% O A+ `% G7 ?" \6 S/ n) D super.getHibernateTemplate().update(data); , p, O0 D4 g6 ]) T9 |3 }4 T& G2 }
}
& {- t! y+ p! p2 ]改为:public void update(Object data) throws Exception {
- x* R* L% H4 B) j4 A- g super.getHibernateTemplate().merge(data); ' t4 `3 L' L0 ~. B% E6 u" L7 }
} ; r1 M7 K7 o& n* e* l7 i
. W6 v; G" w7 L. b; _2 H( s6 y: J3 x0 i" P- U2 W% r# S
|
|