Published: 08 Apr 2009
By: Gabriel Schenker
Download Sample Code

In this series of articles Gabriel Schenker want to show and discuss which pieces are needed to successfully write an application based on NHibernate and Fluent NHibernate.

Contents [hide]

Introduction

In this first part of the series of articles I’d like to give you a step by step introduction into how to prepare your system to use NHibernate in an application. But I do not only want to use NHibernate alone but rather demonstrate its usage in conjunction with Fluent Nhibernate. As you might already know NHibernate is a so called Object-Relational-Mapping tool (ORM) [1] and is a port of the Java based Hibernate to .NET. The current version of NHibernate is 2.1. At the time of writing it’s in a release candidate status. NHibernate 2.1 is feature par with version 3.2.6 of Hibernate.

Fluent NHibernate on the other hand is a framework built on top of NHibernate which dramatically simplifies the mapping of the entities to the underlying data structures.

Your very first NHibernate application series

  • Part 1 In this series of articles Gabriel Schenker want to show and discuss which pieces are needed to successfully write an application based on NHibernate and Fluent NHibernate.
  • Part 2 In this second part Gabriel Schenker continues his overview of the NHibernate OR/M.
  • Part 3 In this part of the series about NHibernate and its sister product Fluent NHibernate, Gabriel Schenker introduces the auto mapping feature of Fluent NHibernate.
  • Stealing from your customers?

    In the past we all have spent a considerable amount of time writing a data access layer for our application. The overall time spent developing data access code could easily be 30% of the overall time used to implement the solution. There is one problem with this fact. Data access code is nothing special, nothing that adds business value to your application. (Nearly) every business application needs some kind of data access. So why would we continue to spend such a huge amount of time writing boring data access code?

    NHibernate can and will take away the burden of our shoulders. Never again you will have to write and maintain stored procedures. Never again you will deal with ADO.NET and the like. When using a modern ORM tool you can concentrate on the core elements of an application, the ones that provide real business value. You can concentrate on the model of the business domain and the business rules there in. Some people that I respect have even pointed out that if you continue to implement your own data access code you are stealing (money) from your customer.

    But this is enough for now. Let’s start to introduce NHibernate and its sister Fluent NHibernate. To make this introduction a little bit more realistic let’s first find an interesting domain. The domain should be well known to most of you people. What else could be a better fit that an order entry system? At the same time – to not make things too complicated – I have to define a rather simplistic order entry system. So let’s start.

    Object Model first approach

    One important change to consider when you develop a so called green-field application (a new application) is that you normally start with the object model of the domain for which you want to develop the application. In the past most of the time the data model was developed first. So you started with the entity relationship diagram (ERD) [2]. On top of that the application was then built. But in this article we want to first concentrate on the object model and let the database schema be generated automatically by NHibernate based on the object model. Don’t misunderstand me; I am not saying that one cannot use NHibernate to develop applications the other way around. NHibernate is also able to deal with the situation where there already is an existing data model and one has to build an application on top of this.

    The domain model

    In our simplistic domain model customers can place orders. An order is entered into the system by an employee who is responsible for it. Orders consist of one-to-many order items. Each order item defines the quantity of a single product the customer wants to purchase.

    Figure 1: Class diagram of the domain

    Class diagram of the domain

    Mapping the domain model

    Once we have our domain model in place we want to be able to store the state (of this model) in some place. Very often this is done by using a relational database management system (RDBMS) like SQL Server, Oracle, IBM DB2 or MySql to name just a few. When you are using NHibernate it doesn’t really matter which database product you’re going to use since NHibernate supports most of the well known database products. Your application will not be tied to a specific database.

    If we use an RDBMS to store our data (or state) then the data is stored in tables. Thus we have to map our object model to corresponding tables in the database. This mapping doesn’t necessarily have to be one to one (and most often it is not). That is we do not always have mapping where one object maps to one table. Very often the content of one table maps to different object. But this topic we will discuss in a later part of this article series. In the past the mapping between the object model and the underlying database has been mainly done by defining XML documents. These were the so called hbm files. This kind of mapping is still supported and used by many developers. Some other developers preferred to decorate the objects and their properties with attributes to define the mapping. The most prominent infrastructure for this is Castle Active Record [3].

    Lately another approach has been very successful. More and more people use it and are very happy with it. In this approach one uses another framework called Fluent NHibernate to define the mapping with the aid of a fluent interface written directly in C#. One often calls this fluent interface an internal DSL (where DSL is the acronym for domain specific language) [4]. The advantage of using Fluent NHibernate for the mapping is that the mapping is type-safe since it is not based on strings. That makes it also much more refactor-friendly than when using XML documents. Another benefit of this approach is that one can define the mappings in C# which is a full blown programming language and not only a data description language as XML is. This fact opens the door for many - previously unthinkable - possibilities since the mapping can now contain logic. I will discuss this fact in more detail in a later part of the series.

    Preparing my system to use NHibernate

    NHibernate and Fluent NHibernate are both Open Source projects. Thus their source is freely available to everybody over the internet. The best way to get the most recent version of the projects is to download the source and compile it on your system. Don’t be afraid by what I just said! It is very easy and straight forward as you will see in a minute.

    Install an SVN client application

    To be able to download the source code from the repository (on the internet) you have to install a so called SVN client. SVN is an OSS source code repository software and is very popular among OSS developers. The probably best and most popular SVN client for Windows is the Tortoise.SVN application. This application is also open source and thus free. Download the installer from the link given below and install it on your computer. You have to reboot after the setup since Tortoise.SVN hooks very deeply into the system.

    http://tortoisesvn.tigris.org

    Once you have done this step you are ready to download NHibernate. But wait a second. We are not going to download NHibernate but rather the Fluent NHibernate project since this project is built on top of NHibernate and thus contains everything we need.

    Download Fluent NHibernate

    Define a new folder on your system where you want to store the source of the Fluent NHibernate project. As an example let’s say you create a folder c:\dev\FluentNH. Right click with your mouse on this folder and choose the context menu item Checkout (which was added when you installed TortoiseSVN). The following dialog will show up

    Enter the URL to the source code repository of Fluent NHibernate. The project is hosted on Google code and the URL for the repository is

    http://fluent-nhibernate.googlecode.com/svn/trunk

    Once you have entered this URL click OK. Now the source code and any libraries needed are downloaded from the web. Depending on the speed of your internet connection this might take a minute or two.

    Setup a new solution

    Define a new folder for the solution we are going to implement. As an example let’s take c:\dev\NHSample1. In this folder create a sub-folders named lib. This sub-folder will contain all libraries we need to develop and test our application. Copy the following files from the Fluent NHibernate build sub-folder to the lib sub-folder defined above.

    Table 1: Libraries needed when using NHibernate and Fluent NHibernate

    File

    Description

    Nhibernate.dll

    This contains the NHibernate framework

    NHibernate.Linq.dll

    Contains the LINQ to NHibernate provider

    FluentNHibernate.dll

    Contains the Fluent NHibernate framework

    FluentNHibernate.framework.dll

    Attention: this file can e.g. be found in the FluentHNibernate.Testing\bin sub-folder of Fluent NHibernate

    Contains types used for unit testing the mapping

    Iesi.Collections.dll

    Contains the definition of some special collections used by NHibernate

    Log4net.dll

    Contains a logging framework used by NHibernate. Hint: This logging framework is very powerful and popular and can also be used by your application.

    Castle.Core.dll

    Base library is needed by Castle.DynamicProxy2.dll

    Castle.DynamicProxy2.dll

    This contains code to generate proxies and is used by NHibernate to make e.g. lazy load possible

    System.Data.SQLite.dll

    Attention: this file can be found in the tools/sqlite sub-folder of Fluent NHibernate!

    This is a lightweight database that we will use for our unit tests. It can be used in file mode and in in-memory mode. The in-memory mode is extremely fast and especially useful in testing scenarios.

    Nunit.framework.dll

    Attention: this file can be found in the tools/nunit sub-folder of Fluent NHibernate!

    This is the most popular framework for unit testing. We will use it to implement our unit tests.

    An even easier way is to just copy the files of the lib folder in the sample code accompanying this article.

    Start Visual Studio and create a new project. Navigate to the c:\dev\NHSample1 folder and open it. As a project type choose Class Library and name the project NHSample1. Call the solution src (this is only a temporary name and will be changed immediately. This “trick” helps us to get the desired folder structure). Once the solution is open locate the solution explorer and right click on the solution node and choose Rename. Call the solution NHSample1 as well.

    We want to always test our mappings when implementing this solution so let’s immediately add another project to our solution. This will be the project containing all our unit tests. The type of this project should also be Class Library and I usually name it UnitTests.

    We are now ready to implement our first NHibernate based solution.

    Implementing and mapping the first object of the domain model

    As told and justified previously we want to keep our domain model rather simple to be able to concentrate on the relevant factors. Let’s start with the customer object. Add a folder to the NHSample1 project and name it Domain. Add a class named Customer to the Domain folder. The class contains the following code

    Now let’s define the mapping for the customer object. Add a folder Mappings to the NHSample1 project. To the Mappings folder add a new class named CustomerMapping. To use the Fluent NHibernate framework for our mappings we have to reference it. So, add a reference to the NHSample1 project and reference the fluent-nhibernate.dll in the lib folder of our solution.

    Figure 3: Adding references to your project

    Adding references to your project

    Now we can define the mapping. Our mapping class has to inherit from the ClassMap<T> base class. The mappings are then defined in the constructor of our class. Thus our class will look as follows so far (note that the generic parameter of the base class is the class for which we define the mapping)

    Let’s start by mapping the ID of the customer object. A customer is an entity and each entity is uniquely identified by its id. In our case the id is of type int to make it human friendly. We could as well choose a GUID as the type of our id but for this first sample we want to have a human easy readable format. Add the following line of code to the constructor

    Note that we have use the HiLo-identity generator of NHibernate. This is the recommended identity generator when using integral ids and having SQL server as a database (it is NOT recommended to use fields of type identity as id fields on Microsoft SQL Server when using NHibernate!).

    The part Id(c=>c.ID) tells the system that we want to define the property Id of our customer class to be the id of the entity. Please note the usage of the lambda expression c=>c.Id to define the mapping. This might look a little bit unusual and strange at the beginning especially when compared with a syntax like Id("Id"). But the former has the advantage to be type-safe where the latter is not. When being type-safe the compiler can check whether the mapping is correct or not. If instead we use strings for the mapping the compiler cannot check for us whether we e.g. made a typo. Only at runtime the wrong code will fail.

    For a good introduction into delegates and lambda expressions you might read the following blog post.

    http://www.lostechies.com/blogs/gabrielschenker/archive/2009/02/03 /step-by-step-introduction-to-delegates-and-lambda-expressions.aspx

    Now let’s map the remaining properties of the customer object. Those are all of type string. Some of them are mandatory and some are not. All of them have a maximal length. Add the following code to the constructor of the class

    With this statement we define the mapping of the property FirstName. First name is mandatory and thus cannot be null. We also tell the system that its maximal length is 50 characters. If we do not explicitely define the name of the column in the corresponding table on the database will be the same as the name of the mapped property. In our case this is FirstName. Of course this can be changed anytime by using the appropriate syntax.

    Our constructor containing the complete mapping will now look like this

    Note how readable the whole mapping is (compare this with XML!). Imagine now that you rename a property in the customer class. The compiler will immediately notify you of the fact, that the mapping has to be corrected too. If you are using a refactoring tool like Resharper [5] then the tool refactors this automatically for you. You might wonder what the Not.LazyLoad() means. By default Fluent NHibernate defines the mappings to use lazy load. But that also means that all properties of our entities would have to be virtual. At the moment we do not need lazy load and thus we reset this setting.

    Test the Mapping

    Now as responsible developers we have to test our mapping. Thus add a class to the UnitTests project and name it CustomerMapping_Fixture. The Fluent NHibernate framework also offers use some infrastructure code that makes the testing of mapping really simple.

    This unit test uses the PersistenceSpecification class to test the mapping and when run should succeed. But to make this work we have to implement the FixtureBase base class which sets up our testing environment. I’ll discuss this in the following section.

    The Test Fixture Base Class

    What we really need is a (NHibernate) session object which we pass as a parameter to the constructor of the PersistenceSpecification class. This is what we will try to provide in the base class. Let me first show the code and then discuss the details

    Before each test is run the method SetupContext of the FixtureBase class is executed. This is due to the fact that this method is decorated with the [SetUp] attribute defined by NUnit [6]. The first thing we need is a configuration. The configuration is needed by NHibernate and contains such elements as the type of database to access and the details of the connection string needed to open a connection to the respective database. Fluent NHibernate defines helper classes which significantly facilitate the task of providing the correct configuration. In our case we declare that we want to use SQLite [7] as database and that we want to use this database in “in memory” mode.

    Once we have the configuration we can define a session source which will be a factory for NHibernate session objects. Every single command executed by NHibernate needs an open session. A NHibernate is similar (but not equal to) a ADO.NET connection. To define a session source we not only need a configuration object but also a class that derives from PersistanceModel and which in the constructor defines where the mapping classes can be found. In our case I have defined such a class and called it TestModel. The TestModel class is very simple and defined as follows

    This class as mentioned above is responsible to inform the system of which mapping classes are used. Here I tell it to scan the whole assembly which contains the CustomerMapping class for (other) classes that derive from ClassMap<T>.

    The last two lines of code of the SetupContext method of the FixtureBase class presented above open a new session object by using the session source defined previously. This session object is then used to create the database schema with the aid of the session source object. Yes, you have heard it correctly; the database schema is created automatically by NHibernate. The model and the mappings provide sufficient information to NHibernate such as that it is able to automatically create the schema.

    That’s all what is needed to successfully start unit testing the mappings defined by Fluent NHibernate.

    In the next part of this series I’ll continue to implement and map the remaining part of the domain model. I’ll discuss some more interesting elements of the mapping and the corresponding tests.

    References

    <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Gabriel Schenker

    Gabriel Schenker is a independent consultant, trainer, mentor and developer. He lives in Switzerland near to Zurich. His special focus is on practicing lean or friction-less software development. This includes practicing TDD, BDD and DDD. He is constantly advocating, promoting and supporting a cont...

    This author has published 4 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    A Feature-driven Comparison of Entity Framework and NHibernate-2nd Level Caching
    Where would you place caching in your layered solution? Two main patterns exist for caching in appli...
    A Feature-driven Comparison of Entity Framework and NHibernate - Queries
    Let's explore what Entity Framework and NHibernate has to offer when it comes to their query capabil...
    A Feature-driven Comparison of Entity Framework and NHibernate—Fetch Plans
    This article is about fetch plans-a recognized and common way for developers to instruct the O/RM ab...
    A Feature-driven Comparison of Entity Framework and NHibernate - Self-tracking entities
    In this article, Dino Esposito introduces self-tracking entities.
    .NET type generation for NHibernate mapping collections
    An overview of .NET type generation for NHibernate mapping collections.

    You might also be interested in the following related blog posts


    Oredev Wrap-Up read more
    Introducing SharePoint 2010 Training at U2U read more
    Silverlight From Zero read more
    WPF 4 (VS 2010 and .NET 4.0 Series) read more
    A new approach to build iGoogle/Facebook like sites with Asp.Net: Kalitte Widget Toolkit read more
    Building A Product For Real read more
    My History of Visual Studio (Part 8) read more
    Microsoft announced the beta release of IIS Application Warm-Up read more
    My History of Visual Studio (Part 6) read more
    URL Routing with ASP.NET 4 Web Forms (VS 2010 and .NET 4.0 Series) read more
    Top
     
     
     

    Discussion


    Subject Author Date
    placeholder No 'build' folder immediately after SVN download Fred Morrison 4/21/2009 9:59 AM
    RE: No 'build' folder immediately after SVN download Clarence Bakirtzidis 6/22/2009 9:16 AM
    placeholder RE: RE: No 'build' folder immediately after SVN download Mathias Buchholz 11/24/2009 6:55 AM
    build error Mathias Buchholz 11/24/2009 6:45 AM
    placeholder RE: build error Sonu Kapoor 11/24/2009 8:08 AM
    RE: build error Mathias Buchholz 11/24/2009 8:16 AM
    placeholder RE: RE: build error Sonu Kapoor 11/24/2009 8:19 AM
    RE: RE: RE: build error Mathias Buchholz 11/24/2009 9:29 AM
    placeholder RE: RE: RE: RE: build error Sonu Kapoor 11/24/2009 9:39 AM
    RE: RE: RE: RE: RE: build error Mathias Buchholz 11/24/2009 12:04 PM
    placeholder RE: RE: RE: RE: RE: RE: build error Mathias Buchholz 11/24/2009 12:08 PM
    RE: RE: RE: RE: RE: RE: build error Sonu Kapoor 11/24/2009 12:09 PM
    placeholder RE: RE: RE: RE: RE: RE: RE: build error Mathias Buchholz 11/25/2009 1:34 PM
    RE: RE: RE: RE: RE: RE: RE: RE: build error Mathias Buchholz 11/25/2009 1:36 PM
    placeholder RE: RE: RE: RE: RE: RE: RE: RE: RE: build error Gabriel Schenker 11/25/2009 2:47 PM
    RE: RE: RE: RE: RE: RE: RE: RE: RE: RE: build error Mathias Buchholz 11/25/2009 4:45 PM
    placeholder Could not load type 'FluentNHibernate.ReflectionHelper' Job Lot 2/13/2011 11:42 PM
    Could you elaborate a bit on this... Ricardo Francisco 5/31/2011 3:37 AM
    placeholder Thanks a lot Jan Nowaczek 9/3/2012 4:09 AM
    Fantastic article, but my test failed Daniel Powley 4/9/2009 5:20 AM
    placeholder Thanks for the walkthrough Noam Gal 4/9/2009 10:28 AM
    Re: Thanks for the walkthrough Gabriel Schenker 4/9/2009 12:00 PM
    placeholder Nice Work Scott Stout 4/9/2009 2:26 PM
    Nice one Michael Hanney 4/10/2009 5:40 PM
    placeholder Shouldn't Entity public override bool Equals use this.GetType() ? Michael Hanney 4/10/2009 6:48 PM
    Re: Shouldn't Entity public override bool Equals use this.GetType() ? Gabriel Schenker 4/10/2009 7:06 PM

    Please login to rate or to leave a comment.