Search code examples
nhibernateconcurrencynhibernate-mappingdatabase-versioning

NHibernate and Integer Columns as Version


I'm trying to create a DB Table, using an NHibernate *hbm.xml mapping file, that will have a Versioning Column for concurrency check. The Versioning column should be a nullable Integer.

Although the Database is created just fine, using the mapping file as reference, the following happen: * The first record is inserted with a NULL value as the Version * The update of the previously inserted records fails with a "Stale Data" exception

In other words, no matter what I do, the Version column is always NULL. I'm somewhat new to the Concurrency Control using NHibernate, so I don't quite understand what I'm doing wrong..

If I use a Timestamp as a Version, everything works just fine. However, my requirement is to use an Integer.. Hence my problem.

This is my Mapping File:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" auto-import="false" assembly="New1.Backend" namespace="New1.BO">
    <class name="Natrio" table="`Natrios`" schema="`dbo`">
        <cache usage="read-write" />
        <id name="Id" column="`Id`" type="System.Int32">
            <generator class="NHibernate.Id.Enhanced.TableGenerator">
                <param name="increment_size">200</param>
                <param name="segment_value">Natrios</param>
                <param name="optimizer">pooled-lo</param>
            </generator>
        </id>
        <version name="Version" column="`Version`" type="System.Nullable`1[[System.Int32, mscorlib]], mscorlib" generated="always" unsaved-value="0">
            <column name="`Version`" not-null="false" sql-type="int" />
        </version>
        <property name="Attribute" column="`Attribute`" type="String" not-null="false" length="100" />
    </class>
</hibernate-mapping>

Any thoughts and/or suggestions would be greatly appreciated!


Solution

  • Why do you need nullable version column? In any case I believe the issue is caused by unsaved-value="0" in your mapping. As default value for nullable column is null - NHibernate thinks that value is already generated and so it's never assigned. You need to set it to null - unsaved-value="null" to make it work with nullable columns. And unsaved-value="0" makes sense for not-nullable types. But better omit this attribute completely and let NHibernate to s

    Another issue with generated attribute. It's about DB generation - so always means that this value is generated automatically by DB. You should remove it or specify it as generated="never".

    I believe the following mapping should work for you:

    <version name="Version">
        <column name="`Version`" not-null="false" sql-type="int" />
    </version>