2013-06-20 40 views
2
NHibernate version: 3.3.2. 

我有一個NHibernate事務,有幾個操作。作爲事務中的一箇中間步驟,我嘗試通過Session.Save插入一個帶有自動增量PK的新實體實例。當保存錯誤並且自動增量Id尚未生成時如何從會話中刪除實體

在某些情況下,由於違反了外鍵值而導致插入錯誤。我發現這個異常是爲了做一些日誌記錄並忽略它,假設插入操作沒有完成,並繼續執行以下步驟。這是一項功能要求,不能更改。根據性能要求,在插入之前驗證值也不是可接受的解決方案。

我的問題:非持久實體已被添加到NH會話緩存但具有空Id。所以,後來我得到這個例外,做一些其他的NH操作時:

NHibernate.AssertionFailure: null id in MyApp.MyPackage.MyClass entry (don't flush the Session after an exception occurs) 

我的問題:我怎麼能拉這惱人的「殭屍」實體關閉會話,所以我成功可以不惜一切結束提交事務腳步?

我不能退出,因爲Id是空的。

我試了一下,得到了以下異常:

System.InvalidOperationException: cannot generate an EntityKey when id is null 

我也不能作爲Clear()我在交易的中間,有一些之前和之後的步驟在當前會話中保存。

我得到的最初的例外有點令人困惑,並且引發了與真正問題發源地不同的地方。這個鏈接給了我一些信息,找出發生了什麼:NHibernate - null id in entry (don't flush the Session after an exception occurs)

+0

你如何驅逐它? Session.Evict(objReference)? – epitka

+0

@epitka是的,我使用調用session.Save時使用的實體實例。它具有屬性Id值= 0,如果它已被正確插入,它應該由Save填充。 – Diana

回答

0

根據NHibernate Manual, 9.8. Exception handling

如果ISession的拋出一個異常,你應該立即回滾事務,調用ISession.Close(),丟棄該ISession實例。 ISession的某些方法不會使會話保持一致的狀態。

我想你必須在你的情況下重新啓動整個交易。

+0

最後,我不得不改變邏輯並犧牲性能來事先檢查FK違規,以避免異常,因爲我沒有找到任何其他方式在異常後恢復會話狀態。 – Diana

0

儘管它很糟糕,我已經能夠通過在'try/catch'中包裝我的zombie.discard()來解決這個問題,並且當我這樣做的時候,它會在你的對象條目中抑制更糟糕的「空id」(發生異常時不要刷新會話)「

我覺得髒。

+0

在我的情況下沒有運氣,即使會話被破壞。不管怎麼說,還是要謝謝你! – Diana

相關問題