Hibernate:具有相同标识符值的不同对象已与会话关联

可能重复:
Hibernate错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话关联

当我使用DAO.update(userbean), session.SaveOrUpdate(e); 抛出exception:具有相同标识符值的不同对象已与会话关联

function如下:

  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 groups = new ArrayList (); private List roles = new ArrayList (); } public class GroupBean{ private List roles = new ArrayList (); } 

每个groupbean都有一个角色列表,这些角色没有更改。

在数据库中,组和角色是多对多映射,

例如,

我们有一个groupbean#1,它的角色是:rol​​ebean#1,rolebean#2;

groupbean#2,其角色是rolebean#1。

现在我创建一个新的userbean#1,它的组是groupbean#1,如果我想将rolebean#1添加到userbean#1,它将抛出exception,如标题描述

我查看了server.log,发现当我使用DAO.save时,saveOrUpdate命令是:

 userbean#1 |---|-----------***userbean.groups | | groupbean#1 | | groupbean.roles | | rolebean#1 # save relebean#1 the first time | | ---done rolebean#1 | | ------done all rolebeans of group.roles | | ---done groupbean#1 | |-----------done all groupbeans of userbean.groups |---|-----------***userbean.roles | rolebean#1 # save rolebean#1 the second time, and throws exception here! | ----done rolebean#1 | ..... |-----------done all rolebeans of userbean.roles 

exception的原因是rolebean#1在一个会话中被保存了两次,并且它们的身份是相同的。

在function保存(E e)中,如果我使用

 session.merge(e); 

更换

 session.SaveOrUpdate(e); 

不会抛出exception,但是角色#1没有关联到userbean#1

有人可以就此提出一些建议吗?

如果我们可以看到您将角色bean分配给用户和组的代码,那么识别确切原因会更容易。

通常,exception告诉我们的是该角色bean有两个版本(两个实例)。 第一个更新,然后Hibernate命中第二个,并识别它是相同的标识符,但角色的不同分离版本。

Hibernate不确定哪个是正确的,并且在saveOrUpdate下,它会抛出exception让你知道。

Merge的合同工作方式不同,因为它会假设您打算再次保存它(即合并我的所有更改),因此将重新附加第二个版本,合并所有更改并保存任何更新。

我发表了关于SaveOrUpdate vs Merge的博客, 其中有一些更详细的信息来解释发生了什么。

如果你想坚持使用SaveOrUpdate,你需要弄清楚你在作业中做了什么,导致将角色的不同实例分配给用户的角色集合而不是组。

否则,如果合并的效果对您有效(符合JPA标准),则使用它。