If in your project, you let NHibernate generate the database from the information you provide with the schema mappings (a thing extremely useful, especially for testing cause you can build up the database in engines like SQLite)...

mmm...where did I heard something similar ?!?!? ah yes...in my previous post: NHibernate: how to control Delete Rule and Update Rule in a foreign key when using SchemaExport

This time I want to focus on giving a proper name to your Primary Key in the table (which is usually auto-generated in NHibernate 1.2, have to check in 2.0+), this can be useful when you need to generate a database dynamically and then you need to build up update or synchronize it with successive versions using SQL scripts.

NHibernate doesn’t offer (yet) a facility to give a name to your primary key (nothing that I found however, I admit I’m not an NHibernate guru, but an average user). You can use an approach similar to that exposed in my previous post.

In this example I’m using SQL Server/SQL Express as my database engine and the queries are built with that in mind.

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
   3:     <class name="SID.Sphera.Controls.Extended.ImageRegion.Entities.ImageSheetData, SID.Sphera.Controls.Extended"
   4:         table="ImageRegionImageSheetData" lazy="false">
   5:         <id name="_Id" access="field" column="IRISD_Id" type="guid">
   6:             <generator class="guid" />
   7:         </id>
   8:         <property name="_Name" access="field" column="IRISD_Name" type="string" not-null="true" />
   9:         <property name="_ResourceId" access="field" column="IRISD_ResourceId" type="guid" not-null="true" />
  10:         <property name="_Width" access="field" column="IRISD_Width" not-null="true" type="int" />
  11:         <property name="_Height" access="field" column="IRISD_Height" not-null="true" type="int" />
  12:         <property name="_BackgroundImageId" access="field" column="IRISD_BackgroundImageId" type="guid"
  13:             not-null="false" />
  14:         <bag name="_sensitiveRegions" access="field" cascade="all-delete-orphan" lazy="false">
  15:             <key column="IRIRD_ParentImageSheetId" foreign-key="FK_IRIRD_IRISD" />
  16:             <one-to-many class="SID.Sphera.Controls.Extended.ImageRegion.Entities.ImageRegionData, SID.Sphera.Controls.Extended" />
  17:         </bag>
  18:     </class>
  19:     <!-- Primary Key Rename -->
  20:     <database-object>
  21:         <create>
  22:             DECLARE @pkName Varchar(255)
  23:             ;
  24:             SET @pkName= (
  25:                 SELECT [name] FROM sysobjects
  26:                 WHERE [xtype] = 'PK'
  27:                 AND [parent_obj] = OBJECT_ID(N'[dbo].[ImageRegionImageSheetData]')
  28:             )
  29:             ;
  30:             Exec sp_rename @pkName, 'PK_ImageRegionImageSheetData', 'OBJECT'
  31:         </create>
  32:         <drop></drop>
  33:     </database-object>
  34: </hibernate-mapping>

Look at line 24: with this query you get the actual name of the primary key which was generated by NHibernate, this is specific to SQL server/SQL express and is you use a different database engine you have to adapt those queries (I know you loose the decoupling to the database engine offered by NHibernate, but you can setup some strategies to load different mappings according to you current dialect).

In line 30 we use a system stored procedure that allow us to rename the object we got before.

If you know a different and more elegant way to reach the goal, please leave me a comment here.

Technorati Tags: ,,

Related Content