2011-09-25 11 views
2

我有一個由nhibernate 3.1開發的項目。 我需要在項目中實現併發。 我添加「版本」,以HBM文件:如何在Nhibernat 3.1中實現併發性

<class name="Person" table="Person_Person" > 

    <id name="Id" type="Int64" unsaved-value="0" > 
     <generator class="native" /> 
    </id> 

    <version name="Version" /> 

    <property name="FirstName" column="FirstName" 
     type="String(255)" update="true" insert="true" access="property" not-null="false" /> 

    <property name="LastName" column="LastName" 
     type="String(255)" update="true" insert="true" access="property" not-null="false" /> 

    </class> 

而且我一個版本字段添加到實體:

virtual protected int Version { get; set; } 

此外,我用int型版本字段添加到數據庫中。

此實現僅適用於一次。 僅當數據庫中的版本值爲'0'時才起作用。 在第一次更新表中的這一行之後,此值更改爲'1'。 但對於下一個更新版本時,字段不爲「0」,例如「1」,此消息拋出異常:

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [RCISP.Domain.Entities.Person#4] 

我應該怎麼辦?

堆棧跟蹤是:

at 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) 
    at 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) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) 
    at NHibernate.Action.EntityUpdateAction.Execute() 
    at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) 
    at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
    at NHibernate.Engine.ActionQueue.ExecuteActions() 
    at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) 
    at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
+0

版本在人類單獨是正確的,但在關係之後,另一個類是問題。例如Family類的關係(一對多)。我將版本字段添加到實體類和兩個hbm文件。它是正確的? – Ehsan

回答

1

看起來像你這樣做是正確的。它應該工作。嘗試以下操作:

  1. 確保沒有其他會話正在修改的同一對象 (StaleObjectStateException你越來越可能合法)。

  2. 確保沒有在數據庫本身更新版本列(觸發例如)

  3. 確保沒有在你的代碼更改版本屬性。它僅適用於NHibernate。

  4. 從id映射中刪除unsaved-value="0"。看看它在那之後是否有效。

  5. 使用堆棧跟蹤和數據庫和對象中的實際版本值(正好在保存對象之前)更新您的答案。

+0

我檢查了這種情況,但我的問題沒有解決。更新行之後版本值是否更改爲「1」?更新行後不應該保持'0'? – Ehsan

+0

對象中的版本值由nhibernate更新,並與更新期間數據庫中的值進行比較。如果您找出問題,這可能是一個好主意:編寫一個可重現問題的獨立應用程序。 – Dmitry

+0

我不明白 我該怎麼辦? 請進一步解釋 – Ehsan

0

我相信你必須打開動態更新才能使樂觀併發檢查工作。見this blog entry

<class name="Person" table="Person_Person" dynamic-update="true"> 
+0

'Version'在我的測試中沒有'dynamic-update'的情況下按預期工作。只有在沒有**版本號或時間戳的情況下版本**才需要「動態更新」? – Dmitry

+0

我檢查了它。沒有解決我的問題! – Ehsan

+0

@Dmitry - 我不知道,也許我誤解了文檔「如果啓用動態更新,您可以選擇樂觀鎖定策略:」http://knol.google.com/k/nhibernate-章-5-鹼性或映射#5%282E%291%282E%293%282E%29%28C2%29%28A0%29class –