As always, business requirement went over existing code base to ask for a minor change that wasn’t compatible with our existing infrastructure: all surrogate keys are unique identifiers (Guid) and all infrastructure was built around that. The business people asked to add to an existing domain entity a natural key – integer identity number (auto increment field), to serve as a reference number.
We had two choices:
- to generate the identity from business code
- to let database manage it for us.
The second approach it preferable for us because it’s the database’s job to generate the keys.
Out of the box NHibernate doesn’t support such a thing. Answers to my question in NHibernate Users discussion group led to the next solution.
Given the class:
public class Entity { public int Id { get; set; } public int Id2 { get; set; } }
First “Id” is the primary key, the second is the key that we want to map to identity column. To have that done we should do two things:
- Map “Id2″ property as “generated”
- Use “database-object” to drop the column generated by NHibernate & create new one, with IDENTITY set on.
The complete mapping:
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="NHibernate.Playground" assembly="NHibernate.Playground" default-lazy="false" xmlns="urn:nhibernate-mapping-2.2"> <class name="Entity"> <id name="Id"> <generator class="increment" /> </id> <property name="Id2" type="int" generated="always" insert="false" /> </class> <database-object> <create> ALTER TABLE Entity DROP COLUMN Id2 ALTER TABLE Entity ADD Id2 INT IDENTITY </create> <drop> ALTER TABLE Entity DROP COLUMN Id2 </drop> </database-object> </hibernate-mapping>
I like the flexibility offered by NHibernate. Even if you don’t have required feature, you can always use naked ADO.NET or raw SQL.
This blog is about things I'm passionated - Software Development, User Experience, gadgets and few other facets of IT that are keeping me busy at work as well as fueling my knowledge and self-improvement demons.
#1 by Stephane on September 8, 2009 - 18:59
I love the internet
Thanks for posting this
It was really helpful
#2 by Zeljko on December 10, 2009 - 20:09
I think, it would be advisable to add update=”false” to your property ID2 mapping, because in an update situation someone could change the key which doesn’t seem appropriate.