NHibernate Mapping – Inheritance

time to read 6 min | 1145 words

I wanted to explore a few options regarding the way we can map inheritance using NHibernate. Here is the model that we are going to use:image

And the code that we are going to execute:

using (var session = sessionFactory.OpenSession()) using (var tx = session.BeginTransaction()) {	session.CreateCriteria(typeof(Party)).List();	session.CreateCriteria(typeof(Company)).List();	session.CreateCriteria(typeof(Person)).List();	tx.Commit(); }

From now on we are going to simply play with the mapping options to see what we can come up with. We will start with a very simple discriminator based mapping (table per hierarchy):

<class name="Party" abstract="true" table="Parties"> <id name="Id"> <generator class="identity"/> </id> <discriminator column="Discriminator" not-null="true" type="System.String"/> <subclass name="Person" discriminator-value="Person"> <property name="FirstName"/> </subclass> <subclass name="Company" discriminator-value="Company"> <property name="CompanyName"/> </subclass> </class>

Which result in the following table structure:

image

And the SQL that was generated is:

Select Party

image

Select Company

image

Select Person

image

But that is just one option. Let us see what happen if we try the table per concrete class option:

<class name="Person" table="People"> <id name="Id"> <generator class="identity"/> </id> <property name="FirstName"/> </class> <class name="Company" table="Companies"> <id name="Id"> <generator class="identity"/> </id> <property name="CompanyName"/> </class>

Which result in the following table structure:

image

And the following queries:

Select Party

image

image

No, that is not a mistake, we issue two SQL queries to load all possible parties.

Select Company

image

Select Person

image

The inheritance strategy is table per subclass:

<class name="Party" abstract="true" table="Parties"> <id name="Id"> <generator class="identity"/> </id> <joined-subclass table="People" name="Person"> <key column="PartyId"/> <property name="FirstName"/> </joined-subclass> <joined-subclass table="Companies" name="Company"> <key column="PartyId"/> <property name="CompanyName"/> </joined-subclass> </class>

Which result in the following table structure:

image

And the queries:

Select Party

image

This is slightly tricky, basically, we get the class based on whatever we have a row in the appropriate table.

Select Company

image

Select Person

image

The final option is using unioned subclasses, which looks like this:

 

<class name="Party" abstract="true" table="Parties"> <id name="Id"> <generator class="hilo"/> </id> <union-subclass table="People" name="Person"> <property name="FirstName"/> </union-subclass> <union-subclass table="Companies" name="Company"> <property name="CompanyName"/> </union-subclass> </class>

Note that it is not possible to use identity with union-subclasses, so I switched to hilo, which is generally much more recommended anyway.

The table structure is similar to what we have seen before:

image

But the querying is drastically different:

Select Party

image

Select Company

image

Select Person

image

The benefit over standard table per concrete class is that in this scenario, we can query over the entire hierarchy in a single query, rather than having to issue separate query per class.