TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常: : J, x% {% f# b, k' O& Y$ Q
Illegal attempt to associate a collection with two open sessions
' B1 P( A1 `- c1.如以下找到的资料之一:
! Y% \9 X2 P* i3 T错误信息: - J3 u8 g. O4 \# ]% d' x1 V
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions;
; |" C* D) j; v9 b8 W7 o& T错误原因:
% E! C" A# g4 t. r) _1. 一个Action在两个线程中同时运行,造成并发。
/ i$ r% c5 f3 I6 S# t; {1 n/ u( V r解决方法: 7 R1 K5 \ g$ p! c0 n+ w& I) v a
1. 阻止重复提交。可以利用struts Token机制。 . ?: z) z0 W n. H5 k
但是还是不能解决我的问题。
: W# V8 J+ E1 p7 ~. f, H+ b* M6 m2.经常debug 测试 终于发现了一个问题: & j5 N Y% R: m2 }4 ?! @+ a
原来属性重名了 & R7 Q0 h- [( b2 w0 e
我在Action中已经注入了实体类
2 M( @9 s" E$ h! Kprivate Mission mission;
& G; N/ Z6 r( b9 A- ?( c在下面某个内部类方法中也重名的定义
+ p$ Y& r5 N3 Z* L7 J+ a5 C( UMission mission = misList.get(0); 1 T' N* h( \ g- a2 M7 U& U* w
并且他们都被调用了同一方法
, r9 v( [" ^, G8 L! F/ H/ e& c3 bmissionBussiness.addData(mis);
' F' u) y" @0 X6 y% ^处理结果:改掉其中的一个属性名,错误仍然存在。
[ h/ \! N$ K4 F; j
. [) j6 ]8 f) K3.找到资料 :
* }$ S4 d! Q4 W3 b4 K 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 1 T6 ?$ j) [1 X6 S3 x
4.最后终于找到一个可以解决我问题的方案:
- g9 V0 A) i1 @, y2 _ 使用hibenate的merge方法代替save、update等方法。
* ?* v$ n/ W* s4 C A4 F. x& `- Tmerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
) z# L& X& P0 w c0 b! a# z! q7 y/ I6 Z% B3 V; J
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
4 x2 u9 o5 l& H$ W [# L* f! y+ j7 F/ o7 s: f/ G9 b/ k
将此方法:public boolean addData(Object data) throws Exception { # S+ m: D* J- A8 @: D/ x
this.getHibernateTemplate().save(data); 6 _$ N' @8 @% w% U4 O+ N1 ]
return true;
0 v3 S. j9 \" _: w' r } % _& e, F; |" B
改为:
. M6 f& Z- ?$ U+ f k, J3 dpublic boolean addData(Object data) throws Exception { 8 E5 {' K$ P; |) N
this.getHibernateTemplate().merge(data);
# C9 I) b" t4 D: ?# S return true; ) j. d4 J& T8 N% z9 n% I, p
}
2 D' q2 T& Y9 }2 T0 X+ ]将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 # X: k8 Z! t( @; q
t2 Q: j# p+ ?& {4 a
将此方法:public void update(Object data) throws Exception {
, H( M" l+ r% _5 v, g+ r super.getHibernateTemplate().update(data); 4 G# q# A, U2 c
}
0 L" k2 t ?, u( z7 f改为:public void update(Object data) throws Exception {
" g) {$ i, J) x8 A$ A& r! M super.getHibernateTemplate().merge(data);
" c. y. ^6 F* n( m4 a0 Q. y } $ ^. W% D" ~' i
& z, x, G- `5 [: ~7 D4 a7 A
8 r1 z% F/ ]7 H) w' l8 {3 f7 j |
|