Creating one-to-one relationship in NHibernate

A one-to-one relationship between two tables can be created by:

  • Adding a column to the parent table with some unique ID of the child table
  • Without any extra column: just inserting the same PK value in both tables

NHibernate supports the second method (correct me) and you can create this relationship using the “foreign” type ID generator and the <one-to-one> tags in both mappings. Today I created the following mappings for two classes named Document and DocumentStatus.

<class name="Document" table="documents">
    <id name="Id" column="id">
          <generator class="foreign">
               <param name="property">Status</param>
          </generator>
    </id>
    <one-to-one name="Status" class="DocumentStatus" constrained="true"/>
    ... other properties ...
</class>

The trick here is just the foreign ID generator class. Now the mapping for DocumentStatus would be fairly simple.

<class name="DocumentStatus" table="documentstatus">
    <id name="Id" column="id">
       ... any generator class ...
    </id>
    <one-to-one name="Document" class="Document"/>
    ... other properties ...
</class>

The classes will have a property of the corresponding type to map this relationship so you can navigate both ways.

class Document {
... other stuff ...
DocumentStatus Status;
}
class DocumentStatus {
... other stuff ...
Document Document;
}

Whenver you insert a new object in Document, the corresponding DocumentStatus object will be created and its PK will be assigned to Document object as well.

Great Stuff!

Advertisements

3 thoughts on “Creating one-to-one relationship in NHibernate

  1. Hi,
    I am trying to use above code in a project and ran into some trouble. I was wondering if you have time to take a look at my code. I’ve uploaded the source code on http://bit.ly/gNlAWr

    I have a one-to-one relationship between a PersonDataContext class and an EmployeeDataContext. I expect the INSERT to cascade from the PersonDataContext to the EmployeeDataContext. However, this does not happen. I’ve tried cascade=’all’ and cascade=’save-update’ on one-to-one relationship element, but it didn’t work.

  2. You do not need a cascade here. It should work without it.

    The problem I see is that your mapping is from Employee to Person but you are cascading from Person to Employee. This should not work. According to the mapping, person is dependent on the Employee, not vice versa. Change the mappings if you want to do that.

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