3

我使用 Hibernate 已经有一段时间了,并且已经习惯了大多数常见的错误消息。大多数人直接指出了这个问题,但我一直遇到这个问题:

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

我理解错误(会话有两个具有相同 ID 的不同对象),但我真的不知道调试代码以查找问题根源的好方法。通常,我查看我当前正在更改的代码,并寻找我加载一个对象并手动创建另一个对象的位置,希望我能在我的逻辑中找到一个简单的错误。但是,我目前正在使用一个不是我编写的、不熟悉的并且没有文档的代码集。我能想到的唯一解决方案是逐行检查代码,希望能找到错误。您知道调试此错误的更好方法吗?

此外,我得到的确切错误来自对 的调用saveOrUpdate(),这让我想知道它是否save()在应该调用时调用update()。有什么方法可以查看 Hibernate 在当前 Session 中的对象以进行调试?

4

2 回答 2

4

saveOrUpdateupdate如果分离的实体已经有一个 ID,则调用。update然后尝试将给定的分离实体附加到会话。由于您在会话中只能拥有给定实体的一个实例,因此如果您在调用时已经在会话中加载了实体(使用 a load、 aget或查询)saveOrUpdate,您将收到此异常。

saveOrUpdate通常应该是打开会话后首先要做的事情之一。如果您必须在更新之前加载实体,您应该使用merge. 我通常更喜欢merge在所有情况下使用,因为它不太容易出错。

您可以使用session.getStatistics().getEntityKeys().

于 2011-10-28T20:01:11.040 回答
1

您可能还想在 Session.Flush 函数中设置断点并检查哪些对象存储在持久化器中。在这里,您可能会找到一些如何跟踪会话打开和会话关闭事件的信息——您可能需要仔细检查对象和事件的PersistenceContext属性。SessionImplOnFlush

要使用源代码进行调试,您不需要重新编译所有 NHibernate 源 - 您可以将 pdb 文件与 zip 源文件绑定(查看http://lowleveldesign.wordpress.com/2011/10/02/debugging -nhibernate-prepare-symbol-files/)。

于 2011-10-30T09:25:42.153 回答