2011-10-28 27 views
1

我已經使用Hibernate一段時間了,已經習慣了大多數常見的錯誤信息。大多數點我直奔問題,但我一直有這個問題的一個:調試Hibernate會話/事務錯誤的好主意?

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

我理解錯誤(會話具有帶相同的ID兩個不同的對象),但我真的不知道一種調試我的代碼以找到問題根源的好方法。通常,我會查看目前正在更改的代碼,並查找加載一個對象並手動創建另一個對象的位置,希望能夠在我的邏輯中找到一個簡單的錯誤。但是,我目前正在使用我沒有編寫,不熟悉的代碼集,並且沒有任何文檔。我能想到的唯一解決方案是逐行瀏覽代碼,希望找到錯誤。你知道更好的方法來調試這個錯誤嗎?

此外,我得到的確切的錯誤是從致電saveOrUpdate(),這讓我想知道它是否調用save()時應該調用update()。有沒有什麼方法可以查看Hibernate在當前會話中進行調試的對象?

回答

3

saveOrUpdate如果分離的實體已經有ID,則調用update。然後update嘗試將給定的分離實體附加到會話。由於在會話中只能有一個給定實體的實例,因此如果您已經在調用時間saveOrUpdate的會話中加載實體(使用load,get或查詢),則會發生此異常。

saveOrUpdate通常應該是打開會話後要做的第一件事情之一。如果在更新之前必須加載實體,則應使用merge。在所有情況下,我通常更喜歡使用merge,因爲它不太容易出錯。

您可以使用session.getStatistics().getEntityKeys()瞭解會話內容。

+0

「並更新嘗試將給定的分離實體附加到會話。」不應該說*保存*而不是*更新*? – RustyTheBoyRobot

+1

+1對於'getEntityKeys' – RustyTheBoyRobot

+0

否。保存使暫時實例持久化,並將實體附加到會話。更新需要一個分離的,修改的實例,並嘗試將其附加到會話。如果會話中已經存在具有相同ID的持久實例,則會引發異常。 –

1

您可能還希望在Session.Flush函數中設置斷點並檢查持久存儲器中存儲了哪些對象。 Here您可能會發現一些有關如何跟蹤會話打開和會話關閉事件的信息 - 您可能需要仔細檢查SessionImpl對象的PersistenceContext屬性和OnFlush事件。

要使用源代碼進行調試,您不需要重新編譯所有NHibernate源代碼 - 您可以使用zip源文件綁定pdb文件(查看http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/)。

+0

感謝您的回覆,但我不使用nhibernate。我仍然會考慮在Java環境中使用你的建議。 – RustyTheBoyRobot

相關問題