Concurrency using ms sql timestamp

44 views
Skip to first unread message

Al

unread,
Jul 3, 2009, 9:37:31 AM7/3/09
to nhusers
I am new to NHibernate though I've had few issues up until now (kudos
to the nhibernate developers and community!). I am unable to
successfully implement a version field in a simple class I have
created. The mapping file is pasted below. No matter what I try I
get the infamous StaleObjectStateException. The error message is
pasted below the mapping file. I should mention that this is occuring
during update. I first retrieve a record from the DB, edit the record
and then save. The only thing I see that may be an issue is that on
retrieve my version class field is null, it does not contain the sql
timestamp data. I am not sure if this is normal behavior or not. I
had been expecting to see the byte[] field populated. Newbie I am.
Thanks for your help.

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="VisualObjectLibrary"
namespace="VisualObjectLibrary.Domain">

<class name="Person" table="HMS.Person" lazy="false" where="tranMode!
='DEL'" >
<id name="personID" type="int">
<column name="personID" />
<generator class="native" />
</id>
<version name="version" column="version" type="BinaryBlob"
generated="always" unsaved-value="null" />
<property name="addressID" />
<property name="firstName" />
<property name="middleName" />
<property name="lastName" />
<property name="email" />
<property name="tranMode" />
<property name="modDate" />
<property name="createDate" update="false"/>
</class>
</hibernate-mapping>


EXCEPTION:
NHibernate.StaleObjectStateException was unhandled
Message="Row was updated or deleted by another transaction (or
unsaved-value mapping was incorrect):
[VisualObjectLibrary.Domain.Person#5]"
Source="NHibernate"
EntityName="VisualObjectLibrary.Domain.Person"
StackTrace:
at NHibernate.Persister.Entity.AbstractEntityPersister.Check
(Int32 rows, Object id, Int32 tableNumber, IExpectation expectation,
IDbCommand statement)
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)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at VisualObjectLibrary.Domain.Person.Save() in C:\AEIT_SOURCE
\AEIT-CONSULTING\Trunk\Core\Libraries\VisualObjectLibrary\Vol\Domain
\Person.cs:line 80
at TestHarness.frmTest.button2_Click(Object sender, EventArgs
e) in C:\AEIT_SOURCE\AEIT-CONSULTING\Trunk\Core\Libraries
\VisualObjectLibrary\TestHarness\frmTest.cs:line 76
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m,
MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage
(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc
(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr
hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW
(MSG& msg)
at
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner
(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop
(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TestHarness.Program.Main() in C:\AEIT_SOURCE\AEIT-CONSULTING
\Trunk\Core\Libraries\VisualObjectLibrary\TestHarness\Program.cs:line
17
at System.AppDomain._nExecuteAssembly(Assembly assembly, String
[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args)
at
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object
state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

Graham Bunce

unread,
Jul 4, 2009, 5:36:46 AM7/4/09
to nhusers
Personally, if you're going for SQL Server timestamp, I've used this:

<version name="Version" column="Version" type="binary" unsaved-
value="null" generated="always"/>

that maps to something like this

private byte[] _version;

My SQL column is defined as thus:

[Version] [timestamp] NOT NULL,

It works ok for me - notice I'm using "binary" and not "binaryBlob".
If I retrieve an existing row then my version field is populated with
the content of the SQL Server field.

Al

unread,
Jul 6, 2009, 8:33:53 AM7/6/09
to nhusers
Thank you I am now able to save without getting the
StaleObjectStateException. It appears after saving though the updated
version value (in the db) is not automatically retrieved and merged
into my entity. Is this normal behavior? Is there an additional step
I can take to ensure this value is retrieved and merged?
Reply all
Reply to author
Forward
0 new messages