TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
hibernate 异常:
: ^) M# Q2 E' g* `" L+ V9 C/ z3 ZIllegal attempt to associate a collection with two open sessions
5 `+ h7 E& Z& U1.如以下找到的资料之一: : M( g- m/ S/ N: m1 Z- a
错误信息:
: @8 C Z: E+ D' H! b! r# Xorg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions;
/ j2 C/ B3 H; I- ?) m! ?, C2 s错误原因: 6 z; p7 G {4 m5 N @
1. 一个Action在两个线程中同时运行,造成并发。 , f/ e4 f, J- d
解决方法:
4 J- E8 Y$ B( R4 ?1. 阻止重复提交。可以利用struts Token机制。
* l: D Q& W. k* E6 ^: }+ H3 }3 M但是还是不能解决我的问题。
( r. D# e9 R V2.经常debug 测试 终于发现了一个问题:
- C0 [3 P0 E. Z2 J$ P' m* ^) o 原来属性重名了 2 a+ k6 J; o. u$ J
我在Action中已经注入了实体类 2 _* b) T5 C+ m
private Mission mission;
2 R' m' R; _: U3 J) K8 N6 J* J/ i, y. Q在下面某个内部类方法中也重名的定义 7 s1 D2 E+ i9 S
Mission mission = misList.get(0); ) P9 J& _* T0 D% s
并且他们都被调用了同一方法 ! I' |5 k0 ~* Y- p: [' e
missionBussiness.addData(mis);
9 I7 _1 o" b: A' W+ D处理结果:改掉其中的一个属性名,错误仍然存在。 1 b4 }, v* B. ?
( A# L5 B% G6 b1 ~3.找到资料 : # N" u2 ~. A4 `" Z% z* w
在pring配置文件中的action bean中添加属性 scope="prototype" 问题依然存在。
9 Q9 M/ A$ o; P% C4.最后终于找到一个可以解决我问题的方案:
% |6 G9 d5 |# l' |: P7 O8 B 使用hibenate的merge方法代替save、update等方法。
! _& I& C. I% G5 Nmerge和saveOrUpdate方法区别在于:merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对 象不会纳入session的管理,再次查询该对象还是会从数据库中取。所以一般建议用merge
5 J! X) d3 |& J$ t9 g% @
2 x* c; r! A" Q0 x2 `8 W8 ^1 O将MissionDaoImpl类中的 this.getHibernateTemplate().save(data); save方法改为了merge方法 : W, L& f/ C* B1 A$ i
0 _& o* ?! f t' `5 E* y) s
将此方法:public boolean addData(Object data) throws Exception {
) J! r: b7 D8 E- ~ g this.getHibernateTemplate().save(data); - }! F' p+ t+ g) Z- ^# p% W2 y
return true; : r( a [! Q% v
}
& |' s" h' m6 {( L# y改为: " [; R4 q) Y' c5 H# P6 L, U5 y
public boolean addData(Object data) throws Exception {
; v3 v+ S8 E1 L& |5 Z this.getHibernateTemplate().merge(data); 5 h E" Z0 j/ k& V1 e2 h
return true; # S. o2 W1 r. Y2 G0 O. D
}
% C7 X! I, m; m! Q$ N6 V将MissionDaoImpl类中的 this.getHibernateTemplate().update(data); update方法改为了merge方法
3 R7 j) [. W4 k1 R; r( I/ G. _$ z X7 M% \8 Q
将此方法:public void update(Object data) throws Exception {
9 a B0 H% v) d' i super.getHibernateTemplate().update(data); ' @4 I% A8 ^3 E. \5 B6 b! w
} " w3 v& X$ j; w! g4 N* \( y; G1 s. A
改为:public void update(Object data) throws Exception { ) l7 E. w7 ~) m/ Y7 P2 p% W
super.getHibernateTemplate().merge(data);
3 h( |& {' O5 B+ k6 G3 p4 M, h( _- c } 7 U, _: o; j' @6 j
% ?$ ~3 v( D+ M3 v
5 b A) O0 s) P/ \0 ?4 A |
|