Introduction to NHibernate, Part 2

 

Last time we introduced setting up the configuration file. This time we will look at the basics of mapping.

Mapping Entities

How you map your entities depends upon your preferred
approach.


Attributes or mapping files

You can use either attributes on classes, or an xml based
mapping file to map between a class and a table. Attributes are less verbose
than xml files because you only need to say how to map to the Db, not what
object you are mapping. Some people also prefer them because they dislike
managing xml files. At the same time the issue with attributes files is that
they do not enforce a clean seperation of concerns. The domain should not know
how it is persisted.

Data First or Domain First

If you are ‘data-first’ or you have a legacy schema to
support then you may want to generate your entity classes from the domain
model. There are a number of templates and tools that could help you.

If you are domain first then you build your domain and then
generate the data schema from it. You can use the SchemaExport class to create
an initial cut of the schema by calling its Execute method. You can also use
Export to create an update schema. This model works well with ideas like
Test-Driven Development and Incremental Re-architecture as it allows you to
keep rebuilding your schema

NHibernate mapping – the basics

Let’s talk about xml based mapping, it’s the oldest and the
cleanest, and the other methods are pretty easy to figure out once you have
that one resolved.

We’ll use a simple model so we can focus on introducing
mapping, instead of delving into its depths.

If you are going to be working on mapping then you should
copy the schemas so that Visual Studio can provide you with intellisense:

Copy nhibernate-configuration.xsd, nhibernate-mapping.xsd,
and nhibernate-generic.xsd to the Visual Studio schemas directory.  By default, the schemas directory is
C:\Program Files\Microsoft Visual Studio 9\Xml\Schemas.

We have a customer

 

    public class Customer

    {

        public Company company { get; set; }

        public DateTime? DateOfBirth { get;
set; }

        public string FirstName {get;set;}

        public int Id { get; set; }

        public string Surname {get;set;}

        public int Version { get; set; }

    }

 

And a company

 

    public class Company

    {

        private ISet<Customer> customers =
new HashedSet<Customer>();

 

        public int Id { get; set; }

        public string Name { get; set; }

        public IList<Customer> customers

        {

            get { return customers; }

            set

            {

                customers = value;

            }

        }

    }

 

Note that we use ISet
for the collection type. Most ORM tools require us to do something similar to support lazy loading: use an interface instead of a concrete
type so that the framework can swap in a proxied collection which in turn asks the ORM
to load the data on demand.

Also note that we are mapping a nullable type. NHibernate
supports nullable types, particularly useful in the case of DateTime which
otherwise generates a date that SQL Server will not accept.

We can create a mapping file to map these tables to a Db.
The convention is to have one mapping file per entity, named after the entity
and with the extension *.hbm.xml. Remember to make sure that you make your
*.hbm.xml file an embedded resource. We usually associate the resource with the
class in the same assembly.


The mapping file

We need to tell NHibernate that it is an xml mapping file:

 

<?xml
version=”1.0″?>

 

and then we need to configure NHibernate itself

 

<hibernate-mapping
xmlns=”urn:nhibernate-mapping-2.2″
assembly=”NHibernateDemo” namespace=”NHibernateDemo.Domain”
default-lazy=”false”>

</hibernate-mapping>

 

Note that we need to check that we are using the create
version of the schema for the version of NHibernate we are building to. In this
case we are building to version 2.2 of the schema and working against the trunk
of NHibernate.

Note that we have turned off lazy loading by default.
NHibernate 2.0 turns on lazy-loading by default, which would means that your
classes need to have virtual methods and properties so that they can be
replaced by a proxy. For now we switch this off. We can still set it for a
relation or class explicitly.

The assembly and namespace attributes are a convenience to
save us re-typing them every time.

Mapping a class

Next we map the class

 

<class
name=”Customer” table=”Customer”>

</class>

 

We mainly need to map a class to a table, if we don’t have a
table yet this is where we name it. We can also define some options at this
level. We can set cascade and lazy-load options for the class and optimize how
update statements are generated. For now we can leave these to focus on how we
map, tweaking them later. It is worth pointing out that NHibernate is optimized
for using a version field to support optimistic locking.

In order to lazy load a class (as opposed to an association)
then we need to make the methods and properties of the class virtual (so that
NHibernate can generate a proxy to wrap our class, that asks for the concrete
class to be loaded when we need it).


Mapping the Entity’s Identity
Column

All entities must have a unique identifier, that is consistent
throughout their lifetime, which the Db represents as a primary key. We denote
an id mapping by using the <id/> element. We set the name of the id
property on the class. Again there is a range of mapping options, for example
setting the default value for new, unsaved entities, so that we, and
NHibernate, can easily recognize unsaved entities.

We need to use the <generator/> element within the
<id/> element to indicate how we create new id numbers when we persist.
For databases which support identity columns (DB2, MySQL, Sybase, MS SQL), you
may use identity key generation. For databases that support sequences (DB2,
Oracle, PostgreSQL, Interbase, McKoi, SAP DB) you may use sequence style key
generation.

Mapping the entity version

NHibernate recommends using a <version/> element for
optimistic concurrency support (as opposed to field-by-field comparison or a
timestamp).

 

  <class name=”Customer”
table=”Customer”>

  <id name=”Id”
type=”Int32″ unsaved-value=”0″>

      <generator
class=”identity”/>

    </id>

    <version name=”Version”>

    </version>

 </class>

 Mapping a property

We map a property to a field by using the <property>
element. We can just supply the property name, though once again there are
options, for example to exclude fields that we never update (i.e. read-only) or
to assign a calculated value.

 

  <class name=”Customer”
table=”Customer”>

    <id name=”Id”
type=”Int32″ unsaved-value=”0″>

      <generator
class=”identity”/>

    </id>

    <version name=”Version”/>

    <property name=”DateOfBirth”/>

    <property
name=”FirstName”/>

    <property name=”Surname”/>

 </class>

 

Next time we’ll look at mapping relationships using NHibernate.

 

 

About Ian Cooper

Ian Cooper has over 18 years of experience delivering Microsoft platform solutions in government, healthcare, and finance. During that time he has worked for the DTi, Reuters, Sungard, Misys and Beazley delivering everything from bespoke enterpise solutions to 'shrink-wrapped' products to thousands of customers. Ian is a passionate exponent of the benefits of OO and Agile. He is test-infected and contagious. When he is not writing C# code he is also the and founder of the London .NET user group. http://www.dnug.org.uk
This entry was posted in ., NHibernate, ORM. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Noraking

    http://www.items4eve.com provide almost everything in EVE-Online , free delivery in 30 minutes, nice Jcustomer support here. Come on and enjoy your wonderful shopping  Eve Online,eve Online Isk, Eve Online Items, Eve Plex ,Eve Online Ship, Eve Online Account http://www.items4eve.comExhumers Ore Hulk Caldari Battleships Raven Navy Issue Full Set Of +5 Improved Implants Gallente Battleships Megathron Navy Issue Gallente Freighters Obelisk Caldari Battleships Raven Capital Industrial Ore Rorqual Caldari Battlecruisers Drake Minmatar Heavy Assault Ships Vagabond Angel Battleships Machariel Gallente Battleships Megathron Caldari Navy Cruise Missile Launcher Energy Grid Rigs Capacitor Control Circuit II Advanced Anti-Ship Rockets Phalanx Rage Rocket Advanced High Precision Light Missiles Bloodclaw Precision Light Missile Standard Auto-Targeting Hydra F.O.F. Heavy Missile I Standard Auto-Targeting Eradicator F.O.F. Heavy Missile I Advanced High Precision Light Missiles Bloodclaw Precision Light Missile

  • jithendra

    Hi,

    Could you please tell me, how can i create classes and mapping files for existing database.

    I have a database which has 100 tables, i want to create classes and xml files automatically, instead of writing code, So could you please tell me, how can i do that? I came to know that, using NHibernate we can do that, that is main benefit for Nhibernate.

    I need your help, so please guide me how to do

    Thanking you in advance

    With Regards,
    Jithendra

  • http://chaisesofa.co.uk chaise sofa

    I am currently learing as much as i can about everything to do with the web this is all a bit far ahead of me at the moment but before long i hope to understand.

  • http://lotro-gold.ogdeal.com/ LOTRO GOLD

    Sell MMORPG Gold And Money to us to get real money!
    Dear player,
    OGDEAL is buying mmorpg virtual currency. We will offer high price to buy your game gold.You can sell WOW gold, sell warhammer gold, sell eve online isk: http://www.eve-online-isk.com , sell silkroad gold, sell maple story mesos, sell lotro gold, sell lotro europe gold, sell aoc gold, sell Lineage 2 adena, sell EverQuest 2 platinum, sell FFXI gil, sell SWG credits, sell gaia gold, sell 2moons dil, sell cabal online alz, sell kalonline geons to : http://www.ogdeal.com .
    Any questions please Contact our site’s live support chat or MSN: ogdeal@hotmail.com , AIM: ogdeal .Thanks !

  • http://lotro-gold.ogdeal.com/ LOTRO GOLD

    Sell MMORPG Gold And Money to us to get real money!
    Dear player,
    OGDEAL is buying mmorpg virtual currency. We will offer high price to buy your game gold.You can sell WOW gold, sell warhammer gold, sell eve online isk: http://www.eve-online-isk.com , sell silkroad gold, sell maple story mesos, sell lotro gold, sell lotro europe gold, sell aoc gold, sell Lineage 2 adena, sell EverQuest 2 platinum, sell FFXI gil, sell SWG credits, sell gaia gold, sell 2moons dil, sell cabal online alz, sell kalonline geons to : http://www.ogdeal.com .
    Any questions please Contact our site’s live support chat or MSN: ogdeal@hotmail.com , AIM: ogdeal .Thanks !

  • http://www.game4power.com buy wow gold

    WoW shares many wow gold of its features with previously launched games. Essentially, you battle with monsters and traverse the countryside, by yourself or as a team, find challenging tasks, and go on to higher cheap wow gold levels as you gain skill and experience. In the course of your journey, you will be gaining new powers that are increased as your skill rating goes up. All the same, in terms of its features and quality, that is a ture stroy for this.WoW is far ahead of all other games of the genre the wow power leveling game undoubtedly is in a league of its own and playing it is another experience altogether.
    Even though WoW is a wow gold cheap rather complicated game, the controls and interface are done in buy warhammer gold such a way that you don’t feel the complexity. A good feature of the game is that it buy wow items does not put off people with lengthy manuals. The instructions cannot be simpler and the pop up tips can help you start playing the game buy cheap world of warcraft gold immediately. If on the other hand, you need a detailed manual, the instructions are there for you to access. Buy wow gold in this site,good for you ,WoW Gold, BUY WOW GOLD.

  • http://www.game4power.com buy wow gold

    WoW shares many wow gold of its features with previously launched games. Essentially, you battle with monsters and traverse the countryside, by yourself or as a team, find challenging tasks, and go on to higher cheap wow gold levels as you gain skill and experience. In the course of your journey, you will be gaining new powers that are increased as your skill rating goes up. All the same, in terms of its features and quality, that is a ture stroy for this.WoW is far ahead of all other games of the genre the wow power leveling game undoubtedly is in a league of its own and playing it is another experience altogether.
    Even though WoW is a wow gold cheap rather complicated game, the controls and interface are done in buy warhammer gold such a way that you don’t feel the complexity. A good feature of the game is that it buy wow items does not put off people with lengthy manuals. The instructions cannot be simpler and the pop up tips can help you start playing the game buy cheap world of warcraft gold immediately. If on the other hand, you need a detailed manual, the instructions are there for you to access. Buy wow gold in this site,good for you ,WoW Gold, BUY WOW GOLD.

  • Daniel Fernandes

    Rick: What about the Great Asteroid that nearly wiped all living animals from the face of the Earth ? :)

  • Rick

    Just the fact that you have to go through all this extra mess to map objects shows how poorly implemented this technology is. LLBL has a UI. Why can’t NHibernate?

  • http://blog.danielfernandes.net daniel fernandes

    A typo I think:
    “If you are ‘data-first’ or you have a legacy schema to support then you may want to generate your entity classes from the domain model.”
    I would have thought “…generate your entity classes from the data model.”

    I’m very much in this situation with a legacy database that is half OLTP half reporting Database and with a plethora of composite keys that bleed all over the place and NHibernate for several reasons doesn’t quite support this model, in particular when keys from the composite keys are used for many to one relationships.
    That’s Persistence Ignorance thrown out of the window!

    Daniel

  • David Perfors

    Great article, thanks for writing :)

    I see a problem though in the Company class (as does my compiler) You are trying to convert an ISet to an IList… That seems not to be possible without casting…