Printed from A Developer website designed for Developers

NHibernate: Mapping Application Domain

Mapping Class Inheritance

There are three different approaches to represent a class inheritance hierarchy.

1) Table per concrete class

This approach uses one table for each (non-abstract) class. All class properties, including inherited properties, can be mapped to columns in the table.

In NHibernate, use a <class> declaration for each concrete class, specifying a different table attribute for each.

Problems with this approach:

2) Table per class hierarchy

An entire class hierarchy is mapped to a single table. The table includes columns for all properties of all classes in the hierarchy.

This strategy is both simple and good for performance.

The concrete subclass represented by a particular row must be identified by a unique value (a type discriminator column).

In NHibernate, use the <subclass> element to define this class hierarchy mapping for each subclass and map the base class using a <subclass> element. Specify, the unique row identifier column using the <discriminator> element in the base class mapping and discriminator attribute in the subclass mapping.

Problems with this approach:

3) Table per subclass

Every subclass that declares persistent properties (including abstract classes and even interfaces) has its own table.

The table here contains columns only for each non-inherited property (each property declared by the subclass) along with a primary key that is also a foreign key of the base class table. The two rows are linked together by their shared primary key value.

In NHibernate, you use the <joined-subclass> element to indicate a table per subclass mapping. NHibernate will then use an outer join when querying the database.

Advantages of this approach:

Mapping Class Associations

Associations refer to relationships between entities, and are mainly unidirectional.

One-to-many associations are the most important and popular type.

Many-to-many associations can be represented as two many-to-one associations. To represent a many-to-one relationship, need to definite two associations. One association mapping the many-to-one side of the relationship, and the other mapping representing the one-to-many side of the relationship.

One-to-one association

There are two different ways to represent one-to-one associations:

Many-to-many association

Use an intermediate association class to represent a many-to-many relationship.

For unidirectional many-to-many relationships:

For bidirectional many-to-many associations:

One-to-many association

Used to map a typical parent/child relationship between two entity persistent classes using a <one-to-many> and a <many-to-one> mapping.

Use a <set> collection mappings for typical parent/child relationships.

Mapping Class Collections

You can use four different approaches to represent a collection.

Using a Set

Using a Bag

Using a List

Using a Map

Mapping Fetching Strategy

NHibernate lets you specify a default fetching strategy in the XML mapping file, with the ability to then override it at runtime in code.

NHibernate provides four different fetching strategies for any assocation: Immediate, Lazy, Eager or Batch.

Immediate Fetching

Lazy Fetching

Eager Fetching

Batch Fetching

The fetching strategy can be overwritten for a particular association using the outer-join attribute for an association, as follows:

For single point associations

Property Attribute Attribute Description
outer-join="auto" Default. Dependant on fetching strategy specified for the class. If class is configured for lazy fetching than NHibernate fetches the association lazily, otherwise NHibernate fetches the association eagerly.
outer-join="true" NHibernate fetches the association eagerly using an outer-join, even if the class has been configured for lazy fetching.
outer-join="false" NHibernate never fetches the association using an outer join, even when lazy fetching is disabled.

For collections

Property Attribute Attribute Description
outer-join="true" NHibernate fetches the collection eagerly using an outer join.
lazy="true" NHibernate fetches the collection lazily, when it is first accessed. This option is preferred for collection mappings, and is the default in HNibernate 2.1.

The correct fetching strategy minimizes the number of SQL statements that have to be executed by lazily, eagerly, or batch-fetching objects.