Search code examples
nhibernatefluent-nhibernate

Fluent NHibernate optimistic lock


I am trying to configure op-locking using fluent nhibernate.

There is a lot of info out there but none seems to fit the scenario I'm in. My class and map are as follows (edited for brevity):

Entity:

public class EmailGroup : CRUDDomainObject<EmailGroup>
{        
    public virtual string Id { get; set; }
    public virtual MailServer Server { get; set;}
    public virtual string FromAddress { get; set;}
    public virtual string ToAddress { get; set;}
    public virtual long Version { get; set; }    
}

Map:

public class EmailGroupMap : ClassMap<EmailGroup>
{
    public const string TABLE_ID = "EMAILGROUP";

    public const string FIELD_ID = "EMAILID";
    public const string FIELD_MAIL_SERVER = "MAILSERVID";
    public const string FIELD_FROM_ADDRESS = "EMLFROM";
    public const string FIELD_TO_ADDRESS = "EMLTO";
    public const string FIELD_VERSION = "VERSION";

    public EmailGroupMap()
    {
        Table(TABLE_ID);

        Id(x => x.Id)
            .Column(FIELD_ID)
            .Not.Nullable()
            .GeneratedBy.Assigned()
            .Length(12);

        References(x => x.Server)
            .Column(FIELD_MAIL_SERVER)
            .NotFound.Ignore();

        Map(x => x.FromAddress)
            .Column(FIELD_FROM_ADDRESS)
            .Not.Nullable()
            .Length(120);

        Map(x => x.ToAddress)
            .Column(FIELD_TO_ADDRESS)
            .Not.Nullable()
            .Length(1000);

        Version(X => X.Version)
            .Column(FIELD_VERSION)
            .Generated.Always()
            .UnsavedValue("0")
            .Access.Property();

        DynamicUpdate();

        OptimisticLock.Version();
    }
}

All looks well to me here, but when I load the entity and modify it, the version number is not incremented. Likewise if I manually increment the version, while a session is open, I get no StaleObjectException.

Does this config look valid to the more experienced eye? If so what else could I be missing?

UPDATE:

After implementing a database managed timestamp the version column is (of course) being incremented. However NHibernate doesn't treat the row as optimistically locked. I captured the update query from the SQL server to check the where clause (truncated for brevity):

exec sp_executesql N'UPDATE [EMAILGROUP] 
SET [EMLDESC] = @EMLDESC, [MAILSERVID] = @MAILSERVID, [EMLFROM] = @EMLFROM, [EMLTO] = @EMLTO, [EMLCC] = @EMLCC, [EMLBCC] = @EMLBCC 
WHERE [EMAILID] = @EMAILID'

Solution

  • Why did you specify Generated.Always()? That tells NHibernate that this isn't a real column but instead calculated by the database. Documentation: http://nhibernate.info/doc/nh/en/index.html#mapping-generated

    Remove that and it should work.