TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
0 s4 Z) s/ e* R* aIllegal attempt to associate a collection with two open sessions
" t1 k7 C1 B" @ y2 [1.如以下找到的资料之一: 9 a( @$ |5 H- ]& @4 t
错误信息:
* d' t6 Q3 h W4 [& M3 k0 T4 aorg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; 3 v9 `- b9 g+ Q- H
错误原因: # _ \& y/ q; W- P/ M# |9 A- B% P
1. 一个Action在两个线程中同时运行,造成并发。 ; [; S3 R! V( q9 \1 w; P6 `' ]
解决方法:
) c$ u! H( ?( A1. 阻止重复提交。可以利用struts Token机制。 ( Z5 G" }' r1 s, X3 g/ u
但是还是不能解决我的问题。
$ M6 s/ X& b( q- U' H) P& P9 W2.经常debug 测试 终于发现了一个问题:
# V" a0 r+ Q* ^ 原来属性重名了
/ z3 \( G( t& i9 r0 s3 r. b. ? 我在Action中已经注入了实体类
6 I( H+ y6 K z5 [' Iprivate Mission mission;
& p5 G& ~9 g# c6 P在下面某个内部类方法中也重名的定义 # Z1 Z, {: l, q2 b
Mission mission = misList.get(0);
: F/ a/ ]2 p- T" q9 c& e! D并且他们都被调用了同一方法
. `5 f: B8 U, f+ r- S5 [missionBussiness.addData(mis); # X4 g* w/ T( }/ N, M0 S2 r
处理结果:改掉其中的一个属性名,错误仍然存在。 ' v6 Q# s) ]9 U& V; x+ X
( f# d5 v, K* q8 z4 `$ x) |2 A3.找到资料 :
& ~ D0 p" r$ L$ a! Y. j$ F8 B 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
, z2 X! {3 I$ `9 G. Y7 A& y7 k2 e4.最后终于找到一个可以解决我问题的方案:
" d6 Q: h, V6 l2 K8 Y2 v 使用hibenate的merge方法代替save、update等方法。
+ Z3 X1 D: K6 m+ J! {$ W* f% Emerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
1 i) L( [2 e$ A3 W. N3 O" w+ O1 o8 t6 `
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
- H* _! n" A3 m y- X' i" r
3 C$ b/ ~7 n/ Y% T6 x/ o; \; b- x1 {将此方法:public boolean addData(Object data) throws Exception { : A( _2 ~( R) d
this.getHibernateTemplate().save(data); 1 ]; d$ l- a6 I! H8 l: V3 P
return true;
! k& I3 G3 h4 V, j6 L } ! `# e: _* X1 ~; H! y l. b1 ^5 J
改为: / w2 B2 @/ R1 r @& |% k
public boolean addData(Object data) throws Exception { : ?6 |9 C+ n& y) i7 P
this.getHibernateTemplate().merge(data); ) Y( c/ g+ C. m9 r9 A: u
return true; , J4 P+ E, M0 G1 g) U! G" z
}
: v* _ o4 y# {+ ^. K% K0 A" J将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
% L6 ?$ Y. J& A; N# d# b, G- X/ g4 C( N, a$ f( G* S' g! R
将此方法:public void update(Object data) throws Exception {
( X$ P/ }) \1 a super.getHibernateTemplate().update(data);
9 z! [9 Q2 ]8 Z) i }
! m3 _. z) l% E, A, g% _9 _改为:public void update(Object data) throws Exception { ! l/ o- \: K" w/ M+ A8 A* R; J
super.getHibernateTemplate().merge(data);
! f. G7 `* O1 Z0 o }
, Y' i' T& K: k! [' X! Q! F0 f! _7 m$ h9 J0 m
! ^$ D" ]+ J1 i: Z
|
|