今天碰到了一个 奇怪的问题 Illegal attempt to associate a collection with two open sessions。 在最后提交逻辑里。 以前也说过, 现在这个项目的事务是利用AOP 加到DAO 层上的, 在EJB 的方法中很容易在一个方法里面多次调用DAO 层。 并且由于是在做mass change 之前要取出原业务对象 然后在merge 上mass change 的数据。 然后在做N 多的校验, 到最后校验通过提交数据。
这个异常的 log 如下:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.exception.NestableRuntimeException.<init>(NestableRuntimeException.java:104) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:403) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495) ~[hibernate-3.2.6.ga.jar:3.2.6.ga]
进入 OnUpdateVisitor.java的第 43 行代码 可以看到
PersistentCollection wrapper = (PersistentCollection) collection;
if ( wrapper.setCurrentSession(session) ) {
的确在我们的DAO 中要保存的对象有一个 List 成员 所以 这个 wrapper 就是Hibernate 在 load 出那个 entity 的时候产生出的对应的PersistentCollection 集合了, 它应该还保留当时的那个DAO 用到的。 我们再到AbstractPersistentCollection.setCurrentSession 方法里看看:
public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
if (session==this.session) {
return false;
}
else {
if ( isConnectedToSession() ) {
CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
if (ce==null) {
throw new HibernateException(
"Illegal attempt to associate a collection with two open sessions"
);
}
else {
throw new HibernateException(
"Illegal attempt to associate a collection with two open sessions: " +
MessageHelper.collectionInfoString(
ce.getLoadedPersister(),
ce.getLoadedKey(),
session.getFactory()
)
);
}
}
else {
this.session = session;
return true;
}
}
}
在这个方法里面程序的行为应该是:
1, isConnectedToSession() 应该返回为true, 当然这个Session 不是当前这个Session,而是开始load 的那个DAO 对应的Session,
2,接下来一行 CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);就返回 null 了,
3 ,if (ce==null) {
throw new HibernateException(
"Illegal attempt to associate a collection with two open sessions"
);
}
解决的方法 有两个:
1, 首先 Object mergedEntity = Session.merge(entity), 然后 saveOrUpdate 这个 mergedEntity。
2, Session.lock (entity, Lock.NONE)。
其实这个 lock 的用法还是从 这个地方google来的, 在此留个记号,需要做进一步的学习。
分享到:
相关推荐
4. SSH 架构中 Illegal attempt to associate a collection with two open sessions 问题 。 解决方法:使用 Hibernate 的 merge 方法代替 save、update 等方法。merge 方法可以把对象转变为托管状态的对象,而 ...
在使用C#与南大通用数据库(GBase)交互时,遇到的一个常见问题是尝试更新Blob或Clob(大型对象)时出现错误:“Illegal attempt to use Text/Byte host variable”。这个问题通常发生在利用CSDK中的ADO.NET驱动进行...
illegal access to protected memory(解决方案).md
在Java开发过程中,有时会遇到“illegal key size”这样的错误,这通常是由于Java加密相关的安全限制所导致的。这个问题在 JDK 7 版本中尤为常见,因为默认配置的Java Cryptography Extension (JCE) 有对密钥长度的...
今日遇到如下错误:java.security.InvalidKeyException: Illegal key size 因为美国法律限制,JAVA默认支持AES 128 Bit 的key, 如果你计划使用 192 Bit 或者 256 Bit key, java complier 会抛出 Illegal key size ...
illegal opcode(解决方案).md
在Java编程环境中,有时会遇到一个常见的错误:"java.security.InvalidKeyException: Illegal key size"。这个错误通常是由于Java安全策略的限制导致的,尤其是当你尝试使用超过默认限制的密钥长度(例如,超过128位...
在Java编程中,`java.security.InvalidKeyException: Illegal key size` 是一个常见的错误,通常出现在加密或解密操作中,尤其是涉及到对称加密算法如AES(高级加密标准)时。这个错误表明您试图使用的密钥长度不受...
"illegal opcode 红屏报错(hp 360 G6安装win2021)问题解决方法" illegal opcode 错误是指在计算机启动过程中出现的致命错误,常见于操作系统安装或升级过程中。该错误会导致计算机无法启动,出现红屏报错。 ...
解决办法。 如在加密过程中出现下面异常: java.security.InvalidKeyException:illegal Key Size 请将两个jar文件按下列操作完成: 如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件;...
在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的...解决方案: 1.升级压缩包里的固件(该固件将SN修改为默认的-1)。 2.进入J-Link Commander,输入exec setsn=XXXXXXXX (XXXXXXXX为你新的SN号)
开发中碰到的报错,问题已解决,写个文档记录一下这个问题及解决方案
Copy the file with .scr extension to your computers win directory (Windows for 98, Winnt for NT) and check in screens saver settings.<END><br>73,Cls_sample_Collection.zip Implement with Class and ...
google或者baidu一下,好多这样的问题,解决的方法都是修改php.ini,把allow_url_fopen给启用,改成 allow_url_fopen = On 这样做可以解决某些人的问题,有人说在php.ini中,有这样两个选项:allow_url_fopen =on...
Illegal Instruction(解决方案).md
对接微信接口中因为jdk8解密长度不够 报错 java.security.InvalidKeyException: Illegal key size 替换路径:(记得备份原有的文件) C:\Program Files\Java\jdk1.8.0_131\jre\lib\security
对于`java.security.InvalidKeyException: Illegal key size or default parameter`这个异常,主要原因是Java默认的安全策略限制了密钥的长度,解决方法是下载并安装JCE Unlimited Strength Jurisdiction Policy ...
illegal function pointer(解决方案).md
illegal memory access(解决方案).md
[] 匹配中括号里的内容[a-z][A-Z][0-9]。 ! 事件。 $ 取环境变量的值。 | 管道。把前一命令的输出作为后一命令的输入,把几个命令连接起来。 |经常跟tee连用,tee 把内容保存到文档并显示出来。 三、通用后...