我已经使用 Hibernate 一段时间了,并且已经习惯了大多数常见的错误消息。大多数人直接指出了问题,但我一直遇到这个问题:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
我理解错误(会话有两个具有相同 ID 的不同对象),但我真的不知道调试我的问题的好方法代码来查找问题的根源。通常,我会查看当前正在更改的代码,并查找加载一个对象并手动创建另一个对象的位置,希望能够在逻辑中找到一个简单的错误。然而,我目前正在使用一个我没有编写、不熟悉并且没有文档的代码集。我能想到的唯一解决方案就是逐行检查代码,希望找到错误。您知道调试此错误的更好方法吗?
此外,我收到的确切错误来自对 saveOrUpdate()
的调用,这让我想知道它是否在应该调用 save()
时调用了 <代码>更新()。有没有办法查看 Hibernate 在当前 Session 中的对象以进行调试?
I've used Hibernate for a little while now and have become accustomed to most of the common error messages. Most point me straight to the problem, but I've been having issues with this one:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
I understand the error (the session has two different objects with the same ID), but I don't really know of a good way to debug my code to find the source of the issue. Usually, I look at the code that I'm currently changing and look for places where I load one object and manually create another, hoping that I can find a simple error in my logic. However, I'm currently working with a code set that I didn't write, that am not familiar with, and that has no documentation. The only solution that I can think of is to go through the code, line by line, hoping to find the error. Do you know of a better way to debug this error?
Additionally, the exact error that I'm getting is from a call to saveOrUpdate()
, which makes me wonder if it is calling save()
when it should be calling update()
. Is there any way to look at the objects that Hibernate has in the current Session for debugging purposes?
发布评论
评论(2)
如果分离的实体已有 ID,则
saveOrUpdate
调用update
。update
然后尝试将给定的分离实体附加到会话。由于会话中只能拥有给定实体的一个实例,因此如果您已在会话中加载该实体(使用load
、get
或查询)在调用saveOrUpdate
时,您将收到此异常。saveOrUpdate
通常应该是打开会话后首先要做的事情之一。如果您必须在更新实体之前加载实体,则应使用merge
。我通常更喜欢在所有情况下使用merge
,因为它不太容易出错。您可以使用
session.getStatistics().getEntityKeys()
了解会话中的内容。saveOrUpdate
callsupdate
if the detached entity already has an ID.update
then tries to attach the given detached entity to the session. Since you can only have one instance of a given entity in the session, if you already have loaded the entity (using aload
, aget
or a query) in the session at the timesaveOrUpdate
is called, you'll get this exception.saveOrUpdate
should generally be one of the first things to do after opening a session. If you have to load the entity before updating it, you should usemerge
. I generally prefer usingmerge
in all cases, because it's less error-prone.You can have an idea of what's in the session using
session.getStatistics().getEntityKeys()
.您可能还想在 Session.Flush 函数中设置断点并检查哪些对象存储在持久器中。 在这里您可能会找到一些如何跟踪会话打开的信息和会话关闭事件 - 您可能需要仔细检查
SessionImpl
对象的PersistenceContext
属性和OnFlush
事件。要使用源代码进行调试,您不需要重新编译所有 NHibernate 源 - 您可以将 pdb 文件与 zip 源文件绑定(查看 http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/)。
You may also want to set a breakpoint in the Session.Flush function and check which objects are stored in the persister. Here you may find some information how to track session-open and session-close events - you probably need to carefully examine the
PersistenceContext
property of theSessionImpl
object and theOnFlush
event.To debug with the source code, you don't need to recompile all NHibernate sources - you may bind pdb files with the zip source file (have a look at http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/).