开发者

How concurrency implementation in Nhibernat 3.1

I have a project by nhibernate 3.1 . I need to concurrency implementation in project. I Add "Version" to hbm file :

 <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>

Also i add a version field to entity :

virtual protected int Version { get; set; }

Also i add a version field to DataBase by int type.

This implementation is correct only for once. It just works when version value in database is '0' . After first update this row in table, this value change to '1'. But for next update when version field is not '0' for example '1' , throw exception by this message:

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

What should I do?

Stack trace is :

   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.AbstractEntityPersiste开发者_如何学JAVAr.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)


Looks like you doing it right. It should work. Try following:

  1. Make sure that no other session is modifying the same object (StaleObjectStateException that you getting might be legitimate).

  2. Make sure that nothing in the database itself is updating Version column (trigger for example)

  3. Make sure that nothing in your code is changing the Version property. It is for NHibernate use only.

  4. Remove unsaved-value="0" from id mapping. See if it works after that.

  5. Update your answer with a stack trace and the actual Version values in the database and in the object (right before you save the object).


I believe you have to turn on dynamic-update to get optimistic concurrency checking to work. See this blog entry.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜