TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常: : C7 l# ?$ H( a' w; `: c9 U
Illegal attempt to associate a collection with two open sessions
$ J5 a% v) B( K. v1.如以下找到的资料之一:
% k' H4 H6 O1 T) @( U: }2 M错误信息: + p+ O; Y* u9 a# d6 X1 V# P' Y. z
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; . [( J# ^6 N1 j( @* Y
错误原因:
. L! O% B {$ M3 o! x1. 一个Action在两个线程中同时运行,造成并发。 7 e" q) `8 T, h& d* T
解决方法: - k7 z5 l8 s- m
1. 阻止重复提交。可以利用struts Token机制。
- ^% V; F# F& w* k' {0 J但是还是不能解决我的问题。 4 s r" g; E, K9 R. q4 X' Q
2.经常debug 测试 终于发现了一个问题: ! E% f$ [# Q4 g0 `
原来属性重名了 2 I S: \1 Q/ Z3 P' D0 N4 ?
我在Action中已经注入了实体类 $ {$ P) m4 `% B# T
private Mission mission; / _- t0 \$ F! H) t# k) k2 P
在下面某个内部类方法中也重名的定义
/ @0 T( k2 Z& H0 EMission mission = misList.get(0);
9 Q+ y1 ]* ^8 u; J# `5 y1 b并且他们都被调用了同一方法
1 j: V' W' \$ S5 B# UmissionBussiness.addData(mis); 6 P- R+ p7 u! w' M/ \
处理结果:改掉其中的一个属性名,错误仍然存在。
8 i! Z9 [- q4 @
" f5 z: W4 g9 U9 y+ f9 A3.找到资料 :
. z1 X4 Z1 _: F 在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。 % n" B: t& ^4 L1 M7 ^3 T
4.最后终于找到一个可以解决我问题的方案:
4 H6 u' k: |+ r6 L# v& J' q6 i 使用hibenate的merge方法代替save、update等方法。
: ~0 l6 X K7 w( ?merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
3 D2 x3 w$ m4 f$ D
( m+ e- W- k+ e* o' r8 J6 q将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法 % B# |% b4 U. _( d+ F
- ?2 M7 ~! m$ G: P+ X
将此方法:public boolean addData(Object data) throws Exception { " K8 I3 R' y7 l6 x& O# J
this.getHibernateTemplate().save(data);
8 r* f" R) d4 _% i4 m: L return true; . ?: k5 f9 {+ h, f. p
} , a8 `* @# b1 M. i! b ]' I. J4 @
改为:
, G9 u8 Q5 }' L3 b, Z7 q0 {public boolean addData(Object data) throws Exception { 1 }% L3 r* c( U" y) B
this.getHibernateTemplate().merge(data); ( B4 o2 p( q" u: b' u/ W
return true;
/ K5 ~5 s6 Z5 Q8 @3 I }
2 T0 \1 \4 Q, I4 y8 E7 v# p将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
, F9 m) F" M( A
: i& f5 I9 j* v0 m) B$ S6 }将此方法:public void update(Object data) throws Exception { 7 h, `* u* D5 m1 ]
super.getHibernateTemplate().update(data);
4 o- o' Q0 F* L2 {3 J8 k } ! F) g# E( \5 ?& \
改为:public void update(Object data) throws Exception { ! Y& B ]: e6 g) h% r
super.getHibernateTemplate().merge(data); " `" Q; l4 Q* `& `5 T$ H. l1 n
}
) M# S$ Y. F# x5 v4 P1 u3 I! D! _
2 u2 I5 D9 o _5 \0 C, G( ~8 ]1 f: }: [9 k
|
|