TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
4 H) c. _; j: s0 }# mIllegal attempt to associate a collection with two open sessions : M8 D% v8 n4 ?- T" w1 S! @" F9 p
1.如以下找到的资料之一:
3 i- H* `( }7 p9 I# Y8 ]错误信息: 8 w* \8 N4 S+ b/ p" j: X! A. z
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; " ^, G& {( s* F" G
错误原因:
0 a# u! Z) K1 i1 o( t1. 一个Action在两个线程中同时运行,造成并发。 : E* n8 D4 B' |
解决方法: . d! E0 p# D f
1. 阻止重复提交。可以利用struts Token机制。
, p* T! |5 f7 T5 A( Y8 h但是还是不能解决我的问题。 ) s, ]5 \: q; D9 K* P9 B
2.经常debug 测试 终于发现了一个问题: ( y! q# ~" X1 w. t% V$ R- v' Y
原来属性重名了
" V) G) J3 u" F! W6 n g1 R 我在Action中已经注入了实体类 4 _# u% D) C4 w0 I7 v
private Mission mission; 9 ^2 g& @! t/ H+ `/ {
在下面某个内部类方法中也重名的定义 ! J/ K$ X5 j: X& p) l2 g. }6 L
Mission mission = misList.get(0); ' t6 ~( W% G+ S/ h0 b9 N
并且他们都被调用了同一方法 2 Y0 O, n+ u* i+ b
missionBussiness.addData(mis); o5 ?! [: j3 J6 `7 k! ?
处理结果:改掉其中的一个属性名,错误仍然存在。
3 v' y/ b0 w# D7 E
5 s1 @0 E, x, x! t+ b3.找到资料 :
& L0 u5 i2 Y1 X 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 5 Y, o( y! E2 s1 N6 D
4.最后终于找到一个可以解决我问题的方案:
( s/ H; n8 {0 K( } 使用hibenate的merge方法代替save、update等方法。 # _/ o, g4 T" _1 I
merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
4 \' [/ S, D. F9 Y" v4 m7 f# i- U5 j1 F
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
/ V, t' o7 e% a
( G1 y9 O7 M% H: r0 g' Z将此方法:public boolean addData(Object data) throws Exception {
' z+ Y% r7 m( M this.getHibernateTemplate().save(data);
) Q- o6 e/ v, [. x" D1 w return true;
2 N+ c( G$ N8 Z) F* H } - m& R. l4 K! O% k
改为:
; }; @6 J: v$ T' G* y, Rpublic boolean addData(Object data) throws Exception {
1 N% u6 b, M$ A+ T' G2 N this.getHibernateTemplate().merge(data);
. ^! _+ C) ?, ` x- a% Q return true;
' O: e* R: C. O7 W7 E } $ @: Z3 O% j8 b$ w* Q! ]( h
将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 1 L9 a0 [& d! o$ z
0 _+ i8 {" ]6 h8 h h
将此方法:public void update(Object data) throws Exception {
1 x, ]: }& d1 C% S( D# c1 g0 f super.getHibernateTemplate().update(data); $ R' y( Y- p O
}
+ u; Z5 l5 ?) t8 ~* i6 D: k+ |* F0 V改为:public void update(Object data) throws Exception {
3 f) t- B( x2 l/ r- F { super.getHibernateTemplate().merge(data); 9 r) f/ t( h" y5 p5 d9 \4 E6 Z3 P
}
8 r: v3 r H4 v/ X- |/ m; r! W; t9 K3 }- `& U
8 ~/ @6 o( b" ? |
|