开发者

Hibernate: different object with the same identifier value was already associated with the session [duplicate]

This question already has answers here: Closed 10 years ago.

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 t开发者_JAVA百科heir 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜