It seems like every single project we begin as developers, no matter how simple, requires some sort of storage. Sometimes, this is a simple collection of values in an XML file or a key-value pair in a properties file.
However, more often than not, we need to have access to larger volumes of data represented in multiple related database tables. In either case, we are generally forced to reinvent the wheel; to create new data retrieval and storage methods for each piece of data that we want to access. Enter NHibernate.
In this chapter, we will discuss:
What is NHibernate
What is new in the latest version of NHibernate
Why we should use it and who else is using it
Where can we get help or even commercial support when we get lost
Put simply, NHibernate is a framework that allows us to talk to a relational database in an object-oriented way. We can store (or as we also often say, "persist") objects in a database and load those objects from the database later on. NHibernate "auto-magically" translates our object-based language to a language that the database understands. That is, NHibernate generates the necessary SQL statements for us to insert, update, delete, and load data.
If we use NHibernate, then we never have to write any code that deals with the fact that there is an impedance mismatch between the way we develop applications in .NET and how a database works. NHibernate has abstracted away this mismatch for us.
Now, let me try to explain what we understand when talking about an impedance mismatch. An application written in .NET is object-oriented. We deal with objects that contain data and logic. Most often, we deal with a single object that communicates with other objects through messages or events. On the other hand, a relational database is all about (big) sets of data. Relational databases are great when it comes to manipulating those sets of data. However, in a relational database, the concept of objects makes no sense. Logic and data live apart.
In a more formal fashion, we can say that NHibernate is an Object Relational Mapper (ORM) tool or framework. NHibernate is a .NET port of Java's Hibernate. It is designed to bring the interactions with the RDBMS solutions in an application code inline with the current object-oriented application design.
NHibernate is not the sole ORM framework for .NET, but it is probably the most mature and feature rich of all. Some of the other frameworks that exist are: Entity Framework from Microsoft, LLBLGen Pro, Subsonic, and Genome, to name just a few. The following screenshot is the NHibernate logo:
NHibernate 3.0 introduces a lot of new features as compared to the previous version. The most important ones are as follows:
NHibernate is now based on .NET 3.5. It makes heavy use of the new concepts that were introduced with this version of the framework. Most notably, this is the usage of expression trees and extension methods. A good sample is the new in-code configuration of NHibernate using a fluent API. As a consequence, NHibernate 3.0 only runs on .NET 3.5 or higher.
NHibernate now contains in its core a totally rewritten LINQ provider, which supports a large part of the full spectrum of LINQ, and overcomes many of the limitations of the previous LINQ provider. The previous LINQ provider was part of the NHibernate contributions and was based on the criteria API. It only supported a limited set of LINQ queries.
A new method has been added about how we can define the mapping between our model and the database. We can now define the mappings in code and add them to the NHibernate configuration. One contribution project already leverages this new possibility. It is called ConfORM. With this API, we can define rules and exceptions to instruct NHibernate how to create our mappings. The whole mapping process is fully convention based. ConfORM is highly extensible and we can easily define our own rules and exceptions.
It is now possible to lazy load specific columns of a table. This makes sense in scenarios where a table contains BLOB or CLOB fields, which need to be loaded rarely as a result of an explicit request. Previously, only whole objects could be lazy loaded.
Detached criteria now also work with stateless sessions.
Besides these new features, there have been a lot of bug fixes and stability improvements.
In the past, we carefully hand-crafted our data access layers for the applications we wrote. We spent as much as 50% or more of our overall time to implement and maintain this data layer. It was not a very challenging task though, and a lot of repetitive coding was involved. For each and every single type of object we wanted to persist in the database, we had to write similar code. We had to write code to insert a new object into the database, to update an existing object in the database, and to delete an existing object from the database. Furthermore, we wrote code to read an existing single object or a list of existing objects from the database. At a minimum, we had to write six methods per object type.
Somehow, we realized that writing this data layer did not really add value to our business application. It didn't make our application specific as it was only infrastructure code. For each and every application we wrote, we had to implement similar code; be it an ordering system used in an e-commerce or a facility management system for an airport, or a portfolio management, or a trading system for a bank. All types of applications needed the same kind of data access layer.
As we were so bored by always writing the same kind of code again and again, we started to think about the possibility to automate this process as much as possible. The first approach was to write code generators, which, based on certain configuration and templates, wrote the data access code for us. This worked to a certain extent. We were very happy about it, as now, finally, we had more time to concentrate on the important problems such as writing and maintaining the business logic and the user interface, which made our applications unique and added real business value to the overall solution.
As we were not the only developers facing the problem of writing the data access code, some people started to write and publish a framework that would solve this problem. This was the birth of the ORM frameworks such as NHibernate.
Nowadays, accessing relational data from an object-oriented application is a solved problem, period! Why would you want to reinvent the wheel? There is absolutely nothing left that is new or yet unresolved. Data access code is not specific to a certain problem domain. (This statement is even true in regard of new storage technologies such as document databases, Google's big table, and others.)
Every application that needs to manipulate data reads and writes this data from or to the data store in exactly the same way.
Thus, writing your own data layer is a waste of time. Somebody even used a much more pronounced phrase to pinpoint this fact, "Writing your own data access layer is like stealing money from your client".
The home of the NHibernate project is at http://www.nhforge.org, while the code is housed at SourceForge (http://sourceforge.net/projects/nhibernate/). NHibernate is an open source project (OSS). Thus, the code and/or the binaries are freely available and can be downloaded from SourceForge.
Throughout this book, we also make use of Fluent NHibernate, which is a sister project of NHibernate and provides a way to fluently define the NHibernate mappings between the model and database. It is also an OSS project and binaries and/or source code can be downloaded from http://fluentnhibernate.org/downloads.
In a later chapter, we will also use a NHibernate contribution project for the validation of the domain entities. The set of NHibernate contribution projects can be downloaded from http://sourceforge.net/projects/nhcontrib/.
If you use Visual Studio 2010 Professional or higher, then there is an even easier method available as to how we can get to the necessary NHibernate (or Fluent NHibernate) binaries. We can use the NuGet extension for Visual Studio to download NHibernate and all its dependencies and automatically make those binaries a part of our projects. The NuGet project (http://nuget.codeplex.com/) is a free, open source package management system for .NET. It is led and sponsored by Microsoft. At the time of writing, the NuGet project is at version 1.3 and is still under heavy development. Nevertheless, it feels ready for professional use and can really simplify the way we add external dependencies, such as NHibernate or Fluent NHibernate, to our solutions. The following screenshot is the NuGet logo:
Unlike with a commercial product, there is no manual available for NHibernate. However, there is a website that is fully dedicated to NHibernate. This website can be found at http://www.nhforge.org and contains a lot of useful information about and around NHibernate. There is also a reference document published on this website. The reference documentation is very detailed and complete, and should be one of the first sources to consult whenever dealing with a very specific problem or setting. There are also many beginners guides, tutorials, and blog posts that can be found here.
The following list presents a couple of blogs that are either mostly dedicated to NHibernate or contain a lot of information around this framework:
NHibernate meta blog at http://nhforge.org/blogs/nhibernate.
NHibernate FAQs at http://nhibernate.hibernatingrhinos.com/.
Fabio Maulo's blog at http://fabiomaulo.blogspot.com. Fabio is the leader of the NHibernate project.
Ayende Rahien's blog at http://ayende.com/Blog/default.aspx. Ayende is one of the main contributors to NHibernate. Search for NHibernate.
James Gregory's blog at http://jagregory.com. James is the leader of the Fluent NHibernate project.
Quite a few books have been written about NHibernate so far. The latest one being the NHibernate 3.0 Cookbook, which is written for intermediate to advanced users of NHibernate. The detailed list of books is as follows:
"Hibernate in Action" by Christian Bauer and Gavin King, Manning Publications Co.: This is probably the first book published about Hibernate and discusses the Java version of the framework
"NHibernate in Action" by Pierre Henri Kuaté, Tobin Harris, Christian Bauer, Gavin King, and Tobin Harris Manning Publications Co.
"NHibernate 2 Beginner's Guide" by Aaron Cure, Packt Publishing
"NHibernate 3.0 Cookbook" by Jason Dentler, Packt Publishing
For any questions you might have regarding NHibernate, there is a Google Group called "NHibernate Users Mailing List". This mailing list is very active and questions are usually answered within hours, if not within minutes. The list can be found at http://groups.google.com/group/nhusers. At the time of writing, this list contained nearly 30,000 messages. The list can be searched by any keyword and is a good source of tips and hints about how to use NHibernate in various very specific circumstances. Mostly, we can find a solution to our problem in one of the existing message threads without even having to post our own question first. This is shown in the following screenshot:
In addition to this (English) group, there exist several language specific (sub-) groups. Currently, there exist groups in Spanish, French, Italian, Portuguese, German, Dutch, and Chinese. The complete list of groups can be found at http://nhforge.org/groups.
One of the more active groups is the Chinese group. The Chinese community not only has a forum, but also a community site at http://home.cnblogs.com/groups/NHibernate. They are currently working on a new community site at http://nhplex.com/.
If you want to discuss the development of NHibernate or become a contributor to the project, then there is also a mailing list available for this purpose: http://groups.google.com/group/nhibernate-development.
However, there are situations where you really want to have someone you can call to get immediate help. Or maybe your company doesn't want to use a technology without having a signed support contract at hand.
At the time of writing, commercial support for NHibernate is available at least from http://nhprof.com/CommercialSupport.
NHibernate is a mature and stable framework and has been around for many years. Many companies have been using it in many different projects. A lot of those projects are mission critical to the respective companies. Other applications that use NHibernate are exposed to high load and perform very well under these stressful circumstances.
Due to political reasons, not all companies wish to disclose their usage of NHibernate.
However, there is still a list of success stories available on the NHibernate website. This list can be found by using the following link:
In this chapter, we have learned what NHibernate is and why we would want to use it. We also briefly discussed the new important features that NHibernate 3.0 brings to the table. As an important aspect, we got all the information we need to find abundant documentation about NHibernate and get community-driven help or even commercial support (if needed). We also learned that NHibernate has a very broad user base and is driving many critical projects around the world in companies of all sectors.
To give you some numbers: over 100 thousand downloads have been registered so far for NHibernate 2.1.2, and more than 35 thousand downloads for NHibernate 3.0 in its first three months of availability.