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

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

问题描述


可能存在重复:


blockquote>



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



函数如下所示:

  public E save(E e){
Session session = null;
尝试{
session = sessionFactory.openSession();
log.debug(session =+ session.hashCode()+save+ e);
session.SaveOrUpdate(e); //这里抛出异常
session.flush();

catch(Exception e1){
log.err(Can not open hibernate session+ e1.getMessage()+cause:+ e1.getCause());
e1.printStackTrace();
}
finally {if(session!= null)session.close(); session = null;}
return e;

$ / code>

userbean是UserBean类的一个实例

  public class UserBean {
private List< GroupBean> groups = new ArrayList< GroupBean> ();
私人列表< RoleBean> roles = new ArrayList< RoleBean> ();
}

公共类GroupBean {
私人列表< RoleBean> roles = new ArrayList< RoleBean> ();
}

每个groupbean都有一个角色列表,它们没有改变。



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

例如,



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

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

我看server.log,并发现,当我用户DAO.save,saveOrUpdate顺序是:

p>

  userbean#1 
| --- | ----------- *** userbean。组
| | groupbean#1
| | groupbean.roles
| | rolebean#1#首次保存relebean#1
| | --- done rolebean#1
| | ------完成了group.roles
|的所有角色| ---做了groupbean#1
| | -----------完成了所有groupbean的userbean.groups
| --- | ----------- *** userbean.roles
| rolebean#1#第二次保存rolebean#1,并在这里抛出异常!
| ---- donebeanbean#1
| .....
| -----------完成了userbean.roles的所有角色

异常的原因是rolebean#1已在会话中保存了两次,并且它们的身份相同。



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

  session.merge(e); 

替换

  session.SaveOrUpdate(E); 

不会抛出异常,但是beanbean#1不会与userbean#1相关联



任何人都可以对此提出一些建议?

解决方案

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



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

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

Merge的合约工作方式不同,因为它会假设您想再次保存它(即合并我所有的更改),因此将重新附加第二个版本,合并所有更改并保存所有更新。 /rel =noreferrer> SaveOrUpdate vs Merge 以及更多的细节来解释发生了什么。

如果你想使用SaveOrUpdate,你需要弄清楚你在分配中做了什么,导致角色的另一个实例是分配给用户的角色集合而不是组。否则,如果合并的效果为您工作(这符合JPA标准),那么就使用它。

Possible Duplicate:
Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

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

the function is like next:

    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 ;
}

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> ();
}

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

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

for example,

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

groupbean#2, which roles are rolebean#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

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

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

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

session.merge(e);

replace

session.SaveOrUpdate(e);

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

anyone can give some suggestions about this?

解决方案

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.

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's not sure which is correct, and under saveOrUpdate, it throws an exception to let you know.

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.

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

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.

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

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

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