Explicitly Specifying the Identity Column Value using Fluent NHibernate

I recently ran into a situation where I was saving to a database table that did not have an auto-incrementing identity column. I didn’t realize that at the time when I was setting up my NHibernate mapping and it caused me a headache for about half an hour attempting to figure out what was causing the problem.

Unfortunately, I didn’t have NHibernate Profiler on the computer I was using so I had to figure it out using SQL Server Profiler but eventually I was able to obtain the raw SQL that NHibernate was generating for me:

 EXEC sp_executesql   N'INSERT INTO [CLIENT]   (SignUpDate, FullName, ClientId)   VALUES (@p0, @p1, @p2);   select SCOPE_IDENTITY()',  N'@p0 datetime,@p1 nvarchar(4000),@p2 int',   @p0 = '2011-07-29 01:56:14', @p1 = N'Randy Burden', @p2 = 50 

I looked at that and went, “What !?”

After a few minutes, I caught on and realized that I needed to modify my mapping to explicitly specify that I would be providing the identity column value or in NHibernate terms, would be using an assigned generator.

The solution was really quite easy using Fluent NHibernate. I simply made this change to my mapping:

Id(x => x.ClientId).GeneratedBy.Assigned();


If your using .hbm.xml files, you would do this:

<id name="ClientId" column="ClientId" type="int" >
  <generator class="assigned" />
</id>


Doing it this way though does force you to also explicitly specify to NHibernate whether the object should use Save() or Update() when using ISession, meaning you cannot use the SaveOrUpdate() method.

 

Resources:

NHibernate Documentation on Assigned Identifiers

Fluent NHibernate Documentation on Id Property