Java Hibernate:具有相同标识符值的不同对象已与会话关联
可能重复:Java Hibernate:具有相同标识符值的不同对象已与会话关联,java,hibernate,session,Java,Hibernate,Session,可能重复: 当我使用DAO.update(userbean)时,session.SaveOrUpdate(e)引发异常:具有相同标识符值的不同对象已与会话关联 函数如下所示: public E save(E e) { Session session = null; try { session = sessionFactory.openSession(); log.debug("session="+session.hashCode()+"
当我使用DAO.update(userbean)时,
session.SaveOrUpdate(e)代码>引发异常:具有相同标识符值的不同对象已与会话关联
函数如下所示:
public E save(E e) {
Session session = null;
try {
session = sessionFactory.openSession();
log.debug("session="+session.hashCode()+" save "+e);
session.SaveOrUpdate(e); //here throws exception
session.flush();
}
catch (Exception e1) {
log.err("Cannot open hibernate session "+ e1.getMessage()+" cause : "+e1.getCause());
e1.printStackTrace();
}
finally { if ( session != null ) session.close(); session = null;}
return e ;
}
userbean是类userbean的一个实例
public class UserBean{
private List<GroupBean> groups = new ArrayList<GroupBean> ();
private List<RoleBean> roles = new ArrayList<RoleBean> ();
}
public class GroupBean{
private List<RoleBean> roles = new ArrayList<RoleBean> ();
}
异常的原因是rolebean#1在一个会话中保存了两次,并且它们的标识相同
在函数save(E)中,如果使用
session.merge(e);
替换
session.SaveOrUpdate(e);
不会引发异常,但rolebean 1与userbean 1不关联
有人能给我一些建议吗 如果我们可以看到将角色bean分配给用户和组的代码,那么就更容易确定确切的原因
通常,异常告诉我们该角色bean有两个版本(两个实例)。第一个得到更新,然后Hibernate点击第二个,并识别出它是相同的标识符,但角色的不同分离版本
Hibernate不确定哪个是正确的,在saveOrUpdate下,它会抛出一个异常以让您知道
Merge的契约工作方式不同,它将假定您打算再次保存它(即,合并我的所有更改),因此将重新附加第二个版本,合并所有更改,并保存任何更新
我在博客上写了更多的细节来解释发生了什么
如果您想继续使用SaveOrUpdate,您需要弄清楚您在分配中所做的工作,这会导致将不同的角色实例分配给用户的角色集合,而不是分配给组
否则,如果合并的效果适合您(这符合JPA标准),那么就使用它
session.SaveOrUpdate(e);