TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
& |( m6 Z% c( B2 B' VIllegal attempt to associate a collection with two open sessions ! |2 Q$ n) W) B- p
1.如以下找到的资料之一:
- W% y2 U2 J# G' G6 a2 R, f' [错误信息:
' M7 T" ?7 ?3 R% f5 F. qorg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; ( u& v) m7 Z2 u" A T+ d
错误原因: $ Y2 v) x z' V* t
1. 一个Action在两个线程中同时运行,造成并发。
7 M9 b3 v9 a6 w9 `0 T6 N解决方法: # U, J! x9 U* |7 W# G5 V
1. 阻止重复提交。可以利用struts Token机制。
& F b: z. d- q0 b1 r但是还是不能解决我的问题。
7 K& N4 g, _$ K! G8 I6 ^$ C; I0 o$ P2.经常debug 测试 终于发现了一个问题:
. w4 u; x0 u9 [) f# i8 z$ e0 c8 R 原来属性重名了 & q4 O, T Q' u
我在Action中已经注入了实体类 & _( k$ Y# ~' s. n) Q, n: f( A2 F, | f
private Mission mission; 4 }5 l( G2 M! h) u( Z; f3 C
在下面某个内部类方法中也重名的定义
7 a* L) @! B' i* ^- KMission mission = misList.get(0); : A+ x8 s# E; p2 @. m0 F
并且他们都被调用了同一方法 9 c6 g" _) o& F) u! o
missionBussiness.addData(mis);
: ~5 K7 w3 h" V处理结果:改掉其中的一个属性名,错误仍然存在。
1 Q9 m2 ? C- s4 _' `' Y5 b
" o( I" ~# T* ?& f3.找到资料 : 8 h# X8 h2 ^0 J5 p5 q9 M2 m
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 4 j; P- s7 c2 r3 @+ A
4.最后终于找到一个可以解决我问题的方案:
9 C3 b5 n. `' o* k) H 使用hibenate的merge方法代替save、update等方法。
0 q, A* k9 l: ~, g; tmerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge * q' N' u% T8 H! o. J' f
$ C- y% e9 I) i2 }/ h4 D" H, g
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法
0 h" E- i" {. F7 |! y |
- p: m% ~' K; ? c将此方法:public boolean addData(Object data) throws Exception { 3 S+ \ V- i# }; ^$ O( f: n
this.getHibernateTemplate().save(data);
# r3 R, U! z! S+ T% | return true;
! M- B6 v3 ?) j: D }
, p0 T, r0 e! _' E: L. l改为: # x1 r. j; F/ G$ E% m& L! W2 P
public boolean addData(Object data) throws Exception { / i+ L/ _( o1 _# m
this.getHibernateTemplate().merge(data);
0 p c5 g p) W7 F0 I return true; . U+ d2 f; r! {0 q
}
/ K2 A6 {: l3 M2 x将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
+ K8 Z- \* L7 w5 P! z: [9 J3 e. [4 Q6 f9 B; h+ x
将此方法:public void update(Object data) throws Exception {
% ?" z6 d, z3 L4 ? super.getHibernateTemplate().update(data); 7 G" [3 Q0 z! t! l3 i( W" n1 w& `& }% z, L
}
! D# n$ b4 j' t( [改为:public void update(Object data) throws Exception { ' s# V7 s$ f- z. u
super.getHibernateTemplate().merge(data); 9 W2 ]1 f# e6 x1 N4 {
} ) G4 W8 O6 P* y0 D+ ]
6 o( I" h7 d" ]; e
F6 n- p3 @8 k i3 h |
|