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