为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

冉冉说 2019-07-25 10:13:50
Hibernate:具有相同标识符值的不同对象已与会话关联当我使用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> ();}每个groupbean都有一个角色列表,这些角色没有更改。在数据库中,组和角色是多对多映射,例如,我们有一个groupbean#1,它的角色是:rolebean#1,rolebean#2;groupbean#2,其角色是rolebean#1。现在我创建一个新的userbean#1,它的组是groupbean#1,如果我想将rolebean#1添加到userbean#1,它将抛出异常,如标题描述我查看了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异常的原因是rolebean#1已在会话中保存两次,并且它们的标识是相同的。在功能保存(E e)中,如果我使用session.merge(e);更换session.SaveOrUpdate(e);不会抛出异常,但是角色#1没有关联到userbean#1有人可以就此提出一些建议吗?
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

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

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

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

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

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

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

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


查看完整回答
反对 回复 2019-07-25
  • 1 回答
  • 0 关注
  • 570 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号