Hibernate:具有相同标识符值的不同对象已经与会话相关联 [英] Hibernate: different object with the same identifier value was already associated with the session
问题描述
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 sessionwhen I use the DAO.update(userbean),
session.SaveOrUpdate(e);
throw the Exception:different object with the same identifier value was already associated with the sessionthe 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屋!