NHibernate 3 (Part 3) Table Per Concrete Class

Previous post
Next post

I want to use the same domain from the previous post:


but this time, I want two tables: one for Notes, another for Pages:

The solution has two projects: a class library containing the domain, and the console project:

The code is at my AjCodeKatas Google code project, under trunk/NHibernate/ItemsTablePerConcreteClass. The code doesn’t include the NHibernate libraries, so you must add the references to the solution. As in the previous example, I added as reference to console project: NHibernate.dll from the NHibernate folder Required_Bins and NHibernate.ByteCode.Castle from Required_For_LazyLoading\Castle. I added the .xsd files (XML schemas to support intellisense when writing the mapping files) from NHibernate folde Required_Bins.

You can download the source code directly from NHibernate3ItemsTablePerConcreteClass.zip. If you need the NHibernate 3.x libraries, check http://nhforge.org or download my first example NHibernate3SimpleMapping.zip, that includes them. Check my first post to review: libraries to add, schemas, configuration file, and mapping files (don’t forget to add as embedded resources).

Note that the domain classes are the same: they don’t change from the previous example. I changed the mapping files, not the code. This is a proof of domain independence of our mapping strategy.

First, the Item.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  <class name="Item" abstract="true">
    <id name="Id">
      <generator class="guid.comb" />
    <property name="Title" not-null="true" />
    <property name="Description" not-null="true" />

First, I removed the discriminator column. There is no such column, because there is no Items table. I added the attribute abstract=”true”. If you forget to add it, then NHibernate “thinks” you have a concrete table for this class. You can remove it, if you have concrete Items that are not Notes, Pages. This is not the case I want to implement: the only “real” items are Notes or Pages. Item is an abstraction in my domain.

The Note.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  <union-subclass name="Note" extends="Item" table="Notes">
    <property name="Content" />

I added the attribute table=”Notes”. And the new element is union-subclass, instead of subclass as in previous example. This new element is the way to say: “the table of this class CONTAINS the columns to save the parent class values”. That is: the table columns are the UNION of the parent class and this class values.

Similar changes for Page.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  <union-subclass name="Page" extends="Item" table="Pages">
    <property name="Url"/>

The main code is practical the same from the previous example:

ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession())
    using (ITransaction tx = session.BeginTransaction())
        Page page1 = new Page();
        page1.Title = "Technical Blob";
        page1.Description = "My Personal Technical Blob in English";
        page1.Url = "https://ajlopez.wordpress.com";
        Page page2 = new Page();
        page2.Title = "My Personal Blob";
        page2.Description = "My Personal Blob in Spanish";
        page2.Url = "http://ajlopez.zoomblog.com";
        Note note1 = new Note();
        note1.Title = "To Do";
        note1.Description = "My To Do List";
        note1.Content = "Practice NHibernate";
        var items = session.Query<Item>(); ;
        foreach (Item item in items)
            System.Console.WriteLine(string.Format("Item {0}", item.Title));

except that this time, I began to use Session.Query<T>, a new extension method for NHibernate sessions, that returns a IQueryable<T> implementing Linq. You MUST add:

using NHibernate.Linq;

to have this method. It is an extension method, not a “natural one” for ISession.

My sources of information:

Book: Jason Dentler’s NHibernate 3.0 Cookbook



Next steps: implement Table per Class strategy, explore one-to-many, lazy collections, etc.Keep tuned!

Angel “Java” Lopez



3 thoughts on “NHibernate 3 (Part 3) Table Per Concrete Class

  1. Pingback: NHibernate 3 (Part 2) Table per Hierarchy « Angel “Java” Lopez on Blog

  2. Pingback: NHibernate 3 (Part 4) Table Per Class « Angel “Java” Lopez on Blog

  3. mick mars

    Somebody essentially lend a hand to make critically posts
    I might state. This is the first time I frequented your
    web page and up to now? I surprised with the research you made to create this actual post incredible.

    Magnificent activity!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s