休眠:具有相同标识符值的不同对象已经与会话相关联 [英] Hibernate: different object with the same identifier value was already associated with the session

查看:27
本文介绍了休眠:具有相同标识符值的不同对象已经与会话相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能的重复:
休眠错误:org.hibernate.NonUniqueObjectException:一个不同的对象相同的标识符值已经与会话相关联

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

when I use the DAO.update(userbean), session.SaveOrUpdate(e);throw the Exception:different object with the same identifier value was already associated with the session

功能如下:

    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 的一个实例

the userbean is an instance of class 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 都有一个角色列表,这些角色不会改变.

every groupbean has a list of roles, which are not changed.

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

in database, group and role is many-to-many mapping,

例如,

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

we have a groupbean#1, it's roles: rolebean#1, rolebean#2;

groupbean#2,哪些角色是 rolebean#1.

groupbean#2, which roles are rolebean#1.

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

now I create a new userbean#1, it's groups is groupbean#1 and if I want to add the rolebean#1 to userbean#1, it will throws the exception like the title descript

查看server.log,发现我使用DAO.save的时候,saveOrUpdate的顺序是:

I look the server.log, and find that when I user DAO.save, the saveOrUpdate order is:

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在一个会话中被保存了两次,并且他们的身份是一样的.

the cause of the exception is rolebean#1 has been saved twice in a session, and their identity is the same.

在函数save(E e)中,如果我使用

In the function save(E e), If I use

session.merge(e);

替换

session.SaveOrUpdate(e);

不会抛出异常,但 rolebean#1 没有关联到 userbean#1

will not throw exception, but the rolebean#1 is not assocaited to userbean#1

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

anyone can give some suggestions about this?

推荐答案

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

It would be easier to identify the exact cause if we can see the code where you're assigning the role bean to both the user and then the group.

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

In general, what the exception tells us is that there are two versions of that role bean (two instances). The first one gets updated, then Hibernate hits the second one, and recognizes it's the same identifier but a different detached version of the role.

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

Hibernate's not sure which is correct, and under saveOrUpdate, it throws an exception to let you know.

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

Merge's contract works differently, in that it will assume you meant to save it again (i.e., merge all my changes), and thus will reattach the second version, merge all changes, and save any updates.

我写过关于SaveOrUpdate vs Merge 更详细地解释发生了什么.

I've blogged about SaveOrUpdate vs Merge with some more detail to explain what's going on.

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

If you want to stick with SaveOrUpdate, you're going to need to figure out what you're doing in the assignment that's causing a different instance of the role to be assigned to the user's role collection versus to the groups.

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

Otherwise, if the effects of merge work for you (which is in line with the JPA standard), then use it.

这篇关于休眠:具有相同标识符值的不同对象已经与会话相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆