Java 休眠错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话相关联

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3609653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 02:37:04  来源:igfitidea点击:

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

javahibernateorm

提问by Sven

Possible Duplicate:
Hibernate: different object with the same identifier value was already associated with the session

可能的重复:
休眠:具有相同标识符值的不同对象已经与会话相关联

I have got almost the same problem like that user.

我遇到了与那个用户几乎相同的问题。

In my situation I load one entity from db, I convert this entity into a DataTransferObject, then I want to edit one attribute, after that I convert it back into an entityObject, then I update that entity and hibernate throws following error:

在我的情况下,我从 db 加载一个实体,将此实体转换为 DataTransferObject,然后我想编辑一个属性,然后将其转换回一个 entityObject,然后更新该实体,并且休眠会引发以下错误:

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

Apparently, the problem is that the object I retrieve from db has the same id as the one I want to update (like it should be) BUT those are not the same objects!

显然,问题在于我从 db 中检索的对象与我想要更新的对象具有相同的 ID(应该是这样),但它们不是相同的对象!

How to manage that? Thank you for help...

如何管理?谢谢你的帮助...

采纳答案by rompetroll

Your problem is that the object you previously loaded still exists in your hibernate session. I see two ways to cope with that.

您的问题是您之前加载的对象仍然存在于您的休眠会话中。我看到有两种方法可以解决这个问题。

1.) tell the hibernate session to merge your modified object with the one in the session

1.) 告诉休眠会话将您修改的对象与会话中的对象合并

session.merge(object)

2.) kick the old object out of the session before writing the updated object to the session. session.clear() might work.

2.) 在将更新的对象写入会话之前,将旧对象踢出会话。session.clear() 可能会起作用。

回答by mhshams

choose either one:

选择其中之一:

1 - you can close the session after loading the entity and open new session for update

1 - 您可以在加载实体后关闭会话并打开新会话进行更新

2 - instead of creating new Entity for update, use the old one and edit it.

2 - 使用旧实体并编辑它,而不是创建新实体进行更新。

3 - detach your first entity from session - session.evict(myEntity)

3 - 从会话中分离你的第一个实体 - session.evict(myEntity)

回答by matt b

Beyond just calling clear()on the session, it sounds like you might have a problem with the way you are using Hibernate:

除了调用clear()会话之外,听起来您使用 Hibernate 的方式可能有问题:

Apparently, the problem is that the object I retrieve from db has the same id as the one I want to update (like it should be) BUT those are not the same objects!

显然,问题在于我从 db 中检索的对象与我想要更新的对象具有相同的 ID(应该是这样),但它们不是相同的对象!

Do you mean to say that you have two distinct entities which have the same ID? If so, then you should find a different field that uniquely identifies different entities.

您的意思是说您有两个具有相同 ID 的不同实体吗?如果是这样,那么您应该找到唯一标识不同实体的不同字段。

回答by Edmondo1984

This is a very common problem with Hibernate. Even if you delete it from the session, the object will stay in Hibernate PersistanceContext and you will have the same problem. The problem is also coming from the fact that session.contains uses object equality, and not equals()to compare the object...

这是 Hibernate 的一个非常常见的问题。即使您从会话中删除它,该对象仍将保留在 Hibernate PersistanceContext 中,您将遇到同样的问题。问题还来自 session.contains 使用对象相等性,而不是equals()比较对象...

The story is the following: you have object A and object B,which are the same logical object, but two different objects in your java heap. and you have long time ago did something with object A in the session.

故事如下:您有对象 A 和对象 B,它们是相同的逻辑对象,但在您的 Java 堆中是两个不同的对象。并且您很久以前在会话中对对象 A 做了一些事情。

Now if you do session.delete(B)you will get the exception, because you are trying to delete an object which has the same primary key as A, but is not A.

现在如果你这样做,session.delete(B)你会得到异常,因为你试图删除一个与 A 具有相同主键但不是 A 的对象。

The solution is simple:

解决方法很简单:

Object findAAgain=session.merge(B);
session.delete(findAAgain);

the merge returns the instance of the object you have in the session first.

合并首先返回您在会话中拥有的对象的实例。