Monday, May 16, 2011

Myotragus Tupples - Automatizing NHibernate Composite Keys

Introduction
Primary Keys are very usually auto-incrementing integers or Guid. Unfortunately, many domains need much more than that. Primary keys are not defined as single column but just as unique. Sooner rather than later you'd find your self in the need for composite primary keys. When using composite keys, it is very useful being able to apply equality functions to key values. Actually, NHibernate requires composite keys to override equality members (Equals and GetHashCode). This article is about making the process of implementing equality functions painless.

Contents
The Model
Automatic Equality Functions
Using the Code
Statistics
Conclusions
Helpful Links


The Model
Let's take a look at the following Domain.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
      assembly="Myotragus.Data.Tupples.Tests" 
      namespace="Myotragus.Data.Tupples.Tests.Domain"> 
<class name="Product"> 
<id name="Id" column="ProductId">
<generator class="identity"/>
</id>
<property name="Name"/> 
</class> 
<class name="Category"> 
<id name="Id" column="CategoryId"> 
<generator class="identity"/> 
</id> 
<property name="Name"/> 
</class>
<class name="CategoryProducts"> 
<composite-id name="Key"> 
<key-property name="ProductId"/> 
<key-property name="CategoryId"/> 
</composite-id>
<property name="CustomDescription"/>
</class>
</hibernate-mapping>

Code Excerpt 1: NHibernate mapping for sample Domain.
In previous code a 3 entities Domain is defined. Product and Category need no explanation. CategoryProducts, in the other hand, does. If you are experienced with NHibernate, you'd probably use a collection within both Product and Category to represent many-to-many relationships. I prefer to leave my POCOs clear of relationships, but that's me. For the sake of this example, we're going to use this mapping the way I would do it in real life. Let's now take a look at the POCOs.

Read more: Codeproject