TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
$ C$ p7 C& m8 `: S! M9 g* @Illegal attempt to associate a collection with two open sessions
7 H v1 g4 }2 E. [% Z8 a; p+ v' v1.如以下找到的资料之一:
& A' u7 P, O) X8 p. n! @错误信息:
% ]0 q H' X L9 R" m( t2 w; X) Forg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions;
2 I3 T, d8 V" I错误原因: 7 r8 d& E- L+ @1 X8 H, [
1. 一个Action在两个线程中同时运行,造成并发。 # a* P7 h* k! e" m0 U+ k* a5 @
解决方法: : e6 n9 n. h% X! U9 w; R# A
1. 阻止重复提交。可以利用struts Token机制。
, E' n8 k* w G. I8 d- C/ Z" q但是还是不能解决我的问题。
; z! E+ c8 X9 K& ~4 Y! Y( N. ^2.经常debug 测试 终于发现了一个问题:
8 E- C5 N' e; s# E7 a( [/ a- N 原来属性重名了 # A: g7 t" r& Y: D9 X
我在Action中已经注入了实体类 * I8 F7 v4 e8 a8 M, |0 W( O9 \
private Mission mission; ' l2 Y0 S- d, }6 `' T: x+ j+ O
在下面某个内部类方法中也重名的定义 ( m& V8 U# q, P( i4 R8 V" o: y# A
Mission mission = misList.get(0); : C0 g0 e( A* U7 r
并且他们都被调用了同一方法
) V" ~" b/ S' h4 T: L2 p- S& AmissionBussiness.addData(mis); 8 ]: S* |0 ]* F% r4 D6 n, ~
处理结果:改掉其中的一个属性名,错误仍然存在。
& ?# ^5 ^ U6 z/ h
/ }% t! L# m( q- i9 B* H3 z. G3.找到资料 :
( W) v7 e( c/ W2 M- _ 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
6 X& J% l5 s6 i3 |) N4.最后终于找到一个可以解决我问题的方案: 8 Y/ e- }* s" d" [' x
使用hibenate的merge方法代替save、update等方法。
% o$ D5 o) | Z2 z, q) y% kmerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
* H i, r0 B3 e( ]
. Y1 Z2 o' o5 @1 y' {将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
, P3 b$ [" f2 D2 i1 f9 U( w; n& E3 S$ M0 x( K' v9 b I5 r1 }, {
将此方法:public boolean addData(Object data) throws Exception { & U5 _& E. a$ h
this.getHibernateTemplate().save(data); , W2 U* i: |% T- a2 t
return true; 5 ~/ { Z9 t6 g8 Y7 G! j7 Z
}
' V% k* H. \# m改为: 0 d: {: p. D |- n( |
public boolean addData(Object data) throws Exception { 5 p: B- W) c n3 g& Y
this.getHibernateTemplate().merge(data); + Q e8 S. n2 v
return true;
1 l9 V1 b( @: S# g9 H% i }
7 Z; K0 U' a3 O; G5 J将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
, K6 Z* C" y& x9 ~5 }/ K
/ T. O6 j: G5 R% h' a/ o& j/ _8 B将此方法:public void update(Object data) throws Exception {
* K1 l( B* z; D; a super.getHibernateTemplate().update(data); ' @6 Y. }# C2 t2 I
}
: b# n1 J% ]1 J% i! O. a改为:public void update(Object data) throws Exception {
/ f+ s9 b# b2 l2 B super.getHibernateTemplate().merge(data); 1 w& v" w) S4 m, g: W3 e
}
& n0 _4 E# Q3 Z! s7 v
& a: Z0 \1 K* D. t" \3 E
- }% Y7 R+ _4 F5 f6 J" c- f/ i9 [ |
|