TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
# x) C1 e. V. O D$ a5 h8 ?Illegal attempt to associate a collection with two open sessions ' t' |9 N3 t/ I+ j8 x/ e! n
1.如以下找到的资料之一:
* i( l( Z4 h2 h3 s' D错误信息:
' Y h: f9 x& O5 w. Zorg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; 5 d& w* T5 {9 ?" n. J
错误原因:
$ q6 K$ n' X% t1 T1. 一个Action在两个线程中同时运行,造成并发。
4 a/ w# W& b$ B" e8 g# Y- f: [解决方法:
8 u" {' O/ U3 M8 N: J9 z: _1. 阻止重复提交。可以利用struts Token机制。 " F% t6 o- K- o1 X: m* |; L; i: o
但是还是不能解决我的问题。 ( I8 ^' v R. x
2.经常debug 测试 终于发现了一个问题:
$ k* N( {8 |2 i8 [, D% F2 R+ L7 ^ 原来属性重名了
9 Z7 S1 A! L$ o3 |5 {; f7 } 我在Action中已经注入了实体类 ( g$ ]( b, p9 b# l% a8 k
private Mission mission;
8 n5 m# c+ n7 N' w1 p3 m在下面某个内部类方法中也重名的定义
' D: D7 \+ o5 Y6 q: P; W0 i2 jMission mission = misList.get(0);
. `) H; x7 |3 T/ z& r" _6 \并且他们都被调用了同一方法 + g# z0 b8 j5 z8 t
missionBussiness.addData(mis);
3 y) L+ C8 [+ I, t' M处理结果:改掉其中的一个属性名,错误仍然存在。 * }) m! T+ [8 H$ S
# P1 N3 r! s+ V3.找到资料 : % t! A: a/ ^4 P' P3 R
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 ( x! i$ _) L- F- t( P: y
4.最后终于找到一个可以解决我问题的方案: ' K. f* R6 z" f+ U, w
使用hibenate的merge方法代替save、update等方法。 . @- n( i6 `. k$ M. u( _$ v
merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge " w4 p0 q% [' ?
! j) Z h( W6 g3 v& ~6 \
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
2 F. K& X3 A; l3 M) x3 o. W0 F" c# k
将此方法:public boolean addData(Object data) throws Exception {
0 R/ s- k% E8 [0 Y this.getHibernateTemplate().save(data); / v" S) z4 J* A; `1 H' W
return true;
v/ I6 f3 A- W9 c7 R } ?8 c' }; w* b: l2 p4 I
改为:
0 Z3 [, b- a/ T$ `public boolean addData(Object data) throws Exception {
u% M, l+ u% S5 k9 ?+ N! n this.getHibernateTemplate().merge(data); 7 S) K( @4 {4 S* H# b! @
return true; 8 P, `2 \0 _7 ?0 \
} & v- `6 k$ n# @5 b$ a4 E. @1 s& y
将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 ( {0 p2 k& d) i0 F* H
3 F6 w4 Q! ^5 w6 G; D
将此方法:public void update(Object data) throws Exception {
# e& F, A8 \* M. ]; X5 E super.getHibernateTemplate().update(data);
$ p! Y5 K( Z, D) w$ Z# P } 6 }0 T w' K" l+ ^
改为:public void update(Object data) throws Exception {
8 _$ J" s2 s7 A super.getHibernateTemplate().merge(data);
/ e* |. p* S/ L* ]- L- P }
! u4 L" u/ Y# }5 `' {$ \# Z) c. O* d
/ Y5 g4 X% u& }
|
|