TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
4 |. Q- o# y' q Y8 t4 d" I4 ~Illegal attempt to associate a collection with two open sessions
5 \$ d4 x9 d' l. A' b' Z1.如以下找到的资料之一:
4 F9 z/ m' D6 A0 y/ E. A错误信息: 3 q4 g* h# O, |% g6 ^3 `0 L) L+ i
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; ! M* N0 }% Y! s) @
错误原因: ' p5 u9 I/ F! S9 z# Y
1. 一个Action在两个线程中同时运行,造成并发。
* t' i' v, {% h& b8 l解决方法:
5 A& c5 ?6 F: K% ~# Y8 f; t1. 阻止重复提交。可以利用struts Token机制。
1 W/ o3 V6 e7 u) t但是还是不能解决我的问题。
: ]$ n7 L3 P7 D2.经常debug 测试 终于发现了一个问题:
. v8 E5 j/ X7 f0 q3 } e6 A( W 原来属性重名了 ' _" E7 c. l' I
我在Action中已经注入了实体类 $ Y% S, S: @9 `) L+ H( K* [, e# \
private Mission mission;
. [- a1 }! W7 ~- D& K) C* `在下面某个内部类方法中也重名的定义 . k: Y; ?* ^" w2 J! s
Mission mission = misList.get(0); . ^7 s( M1 `6 a
并且他们都被调用了同一方法
5 n0 K q' H3 f! ZmissionBussiness.addData(mis);
3 G) U1 t* m0 d _; L处理结果:改掉其中的一个属性名,错误仍然存在。 - T. l% H( ^7 P6 z+ a) ?
) c0 J7 h/ M) @' X3 U6 K3.找到资料 : + c% S9 W/ f4 G- X
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 9 J% q" ~1 O* f
4.最后终于找到一个可以解决我问题的方案:
! h, c* a4 L) R) W7 i 使用hibenate的merge方法代替save、update等方法。
: l8 x& R* ^0 v9 F' N+ Gmerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
. E$ [0 A) q( L6 V4 o
3 s1 z5 n6 k, Z& b8 v8 J2 t将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
. b( p4 y2 A: }" F' E) Q% K7 I! [# o1 T$ ~ O
将此方法:public boolean addData(Object data) throws Exception { ) u" s5 |5 y: S3 b2 ~: X: ]
this.getHibernateTemplate().save(data);
0 K9 |" O' g/ Q+ W return true;
+ |( ~) L4 v" N& U3 Q1 Y( F } 1 j4 h, z3 u' g
改为: ( g7 r; q) j2 S
public boolean addData(Object data) throws Exception {
8 N7 _" l4 R- R9 H J this.getHibernateTemplate().merge(data); ; H* N! ?3 c; ]* i0 t& c2 B' x/ S
return true;
) Z/ P5 I/ K1 i4 x, D7 f" s } 7 I- ?, A, `% I* ]' H; d9 ^$ U
将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 ' j( S, b) v+ @+ e: K! p& d
6 }: E0 {' `5 j: Q6 c+ Y t+ n
将此方法:public void update(Object data) throws Exception { * j! ?) z5 I( }+ B& l8 `: B+ r- G7 b
super.getHibernateTemplate().update(data); 6 { x9 F# f' E# x) _
} 7 v3 l& }6 j' f; O( @* l. K
改为:public void update(Object data) throws Exception {
. K0 G5 b$ w, ?; R$ K# y super.getHibernateTemplate().merge(data);
2 \$ v9 u, c: |# v* Y* y9 K } ) u- A: h5 V \' E. Q' i
7 M. J$ a$ K. p% r1 m0 e' T0 T+ c
4 T) e5 y" b- B. Y1 R |
|