TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
9 T8 T u& y, G* j, j/ r! i% RIllegal attempt to associate a collection with two open sessions ' `' y& m2 U( H- q
1.如以下找到的资料之一: ; ?/ s# I% f' M, M( x& u
错误信息: ) Z$ z+ T Y) A% y
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; 1 {- s# f. |# _+ ]- F- l2 \! q5 ^
错误原因:
) F1 S8 k: u' |& q1. 一个Action在两个线程中同时运行,造成并发。
H/ I( K3 D' Q/ f, ?解决方法:
7 h7 R, A) J) J( h1 C1. 阻止重复提交。可以利用struts Token机制。 6 M. J2 I7 M* @' Q0 m8 L4 `
但是还是不能解决我的问题。
. J" C1 s- }4 e2 [# Q+ r1 ]% L3 d2.经常debug 测试 终于发现了一个问题: # G4 `$ S/ j9 W5 z+ M
原来属性重名了
& Q5 s; p% E3 l 我在Action中已经注入了实体类 2 `- Q# ?5 r# U5 R5 q# J. ?6 h
private Mission mission;
* R0 V4 N* S8 {. U$ H3 \在下面某个内部类方法中也重名的定义 * V+ T z! U) {# x. Q
Mission mission = misList.get(0); 6 @! r0 A9 J3 P% J* L
并且他们都被调用了同一方法 & G- @& X* M- Q5 o" E8 \- i3 j# }) T
missionBussiness.addData(mis); # U4 @% w1 _( C5 d# N$ L: A
处理结果:改掉其中的一个属性名,错误仍然存在。
2 d- A: C* Z1 N
" ?" M* x$ s& N8 A* d3.找到资料 : 1 R. i' ^8 ~" M5 r3 p- M( y: G* H
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
; m1 w9 h! z- p, Y0 x4.最后终于找到一个可以解决我问题的方案:
7 P# b6 S* U; y# a+ `' h 使用hibenate的merge方法代替save、update等方法。 % a$ e* L: n8 x7 C/ v* C: w! @
merge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge ; ^ K" {/ f% o8 F( G5 |) S6 d
$ [, l% t0 A; e. I0 |* }0 k
将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法 $ n& [) H/ v% g, T
1 o$ j$ E2 S0 C4 s( M
将此方法:public boolean addData(Object data) throws Exception {
E" h% Z! q u this.getHibernateTemplate().save(data);
' F( b$ v2 Y" E0 S& [5 w5 A3 k return true; ) n: t" K5 |$ k1 _" _- ?" Z; L: `
}
6 S% a) z3 m/ N+ f改为: 6 ]- K2 J' ^5 c$ B, a
public boolean addData(Object data) throws Exception { ) G; l" s9 j3 u4 |
this.getHibernateTemplate().merge(data); ; n3 g8 G0 \ ~2 [* b" v% Y( z
return true;
1 [8 Y. U( u( o% K } % o2 v' }( D, v) D/ g2 `/ s
将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法 , l7 C# Q: F$ W# r d
+ n5 A% B: L, b, a% T3 H3 U将此方法:public void update(Object data) throws Exception {
4 {' V3 ?- `5 [5 V9 |0 j/ r super.getHibernateTemplate().update(data); * Q* F7 c. ~) ^( [
} ( i( R' x/ J8 A. P# ?& E$ E3 L5 g" D
改为:public void update(Object data) throws Exception { 1 v: d0 z0 b$ r/ A5 R B3 o
super.getHibernateTemplate().merge(data);
5 `5 s6 @, c" g& h }
( `- n \0 M& C# b4 P4 F9 k* n- g" [4 L k
; l$ H+ ]3 F3 F
|
|