2012-04-12 56 views
1

我使用了Repo模式,並且設置了測試來複制我的HTTP請求,然後在測試完成後導致在工作單元上進行處置。Nhibernate Flush在應該沒有的地方導致更新

看起來,在執行一個HQL語句之後,然後調用displose(這又調用flush)它導致跨越各個元素的更新。

很bizzare--有沒有人遇到過這個?

這是我的HQL語句,它的執行:

_session.CreateQuery("select distinct t from TaskEntity as t").List<T>() 

我拉這回它最簡單的形式 - 並注意HQL語句是不能直接在的createQuery。

這裏是堆棧跟蹤我得到:

BM.Data.Informix.IfxParameterCollection.b(Int32 A_0) 
IBM.Data.Informix.IfxParameterCollection.GetParameter(Int32 index) 
System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index) 
NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) 
NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) 
NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session) 
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) 
NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) 
NHibernate.Action.EntityUpdateAction.Execute() 
NHibernate.Engine.ActionQueue.Execute(IExecutable executable) 
NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
NHibernate.Engine.ActionQueue.ExecuteActions() 
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) 
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
NHibernate.Impl.SessionImpl.Flush() 
Case.Data.SQL.NHibernateUnitOfWork.Dispose() in C:\Projects\Case System\Dev\WorkingBranch\Src\Case.Data.SQL\NHibernateUnitOfWork.cs: line 46 
Case.Domain.Tests.TaskServicesTests.TakeDown() in C:\Projects\Case System\Dev\WorkingBranch\Src\Case.Domain.Tests\TaskServicesTests.cs: line 40 
+0

我可以問你如何觀察到延遲加載發生? – Rippo 2012-04-12 12:55:29

+0

我正在通過NHibernate profiler來觀察它 - 這個問題似乎已經消失了,現在正在被更新語句嘗試被調用 - 我只是有一個HQL語句被執行 - 我將編輯我的問題以適應。 – 2012-04-12 15:39:49

回答

4

我遇到過類似的問題。我會先告訴你這是什麼原因。當NHibernateDB中獲取一個實體時,它會爲它的道具賦值。很少有道具在DB中有空值,但在類定義中不是Nullable類型。所以NHibernate分配給他們一個默認值,例如。 0intDateTime.MinValuedatetime等當你調用commit的事務,NHibernate重新檢查屬性的值與DB值,自應該有Null值現在有一個默認值的道具,NHibernate認爲價值已改變,導致更新。

解決方案:

  1. 使用nullable datatypes以郵遞類的道具與 ?固定他們,但對我來說這是造成其他問題。
  2. 將您的物業地圖設爲Not Null類型,但在大多數情況下,這不是優選的 。
  3. 我使用的解決方案:我指定的默認值在實體的構造函數中 道具,所以不是在DbNhibernate節省Null值 節省一些默認值,這將停止 調用不必要的更新。

您可以通過google NHibernate ghostbuster進一步瞭解此問題。

+0

完美!儘管剛剛過了一年......但這完全描述了這個問題!現在一切都使用Nullable(),我們也關閉了NH中的TrackChanges功能 – 2013-04-17 14:37:35

1

NHibernate的通常運行更新時有短暫的或分離的實體,它是不知道。也就是說,它不知道它是否擁有父項來管理它的實體,或者它不確定該實體是否髒。這通常是某個地方出現錯誤映射的症狀(對某些父節點缺少反轉),或者實體上沒有版本或日期列。

相關問題