NHibernate Part 1: Hello World with NHibernate

The Code

Updated code available for NHibernate 2.0.1.GA here.
The toolingset used is Visual Studio 2008 and Sql Server 2008

It’s been a few years now since I read for the first time about object relational mapping. It where a series of articles from Scott W. Ambler. At that time, this was a completely new appraoch but it got my attention firmly. It would however take some time and more reading to really get the importance of the concept.

The idea seeded to start experimenting with this concept and finally that time has come. After reading – searching the internet for some articles on NHibernate i didn’t realy find a “Hello World” type of application, with minimal overhead, that would get me in quickly. Most of the examples I found started with several objects and tables connected, implemented over several assemblies. Allthough they where good articles, what I wanted was a simple sample application, with one class mapped to one table showing me how to do a read operation with a minimum of overhead.

I decided to create this application myself.

In the sample application I used NHibernate version 1.0.0.0 You can download it from here. The site has the Java and .NET versions, so you will have to go to the .NET section and download it from there. The downloaded zip file contains the sources and pre-compiled versions of the library. I used the pre-compiled version for this sample.

Tooling

When writing articles about programming one has to decide what tools to use. To reach as much people as possible, I’ve decided to use free tools only. As such, following tools are used:

  • SharpDevelop: An open source development IDE for C#. You can obtain it at following link. Just go to the download section. You will need to install the .NET runtime first. You might even consider installing the SDK instead which comes with documentation on developing with .NET
  • MySQL: A free database server. You can download it here. Choose the MySQL Community Edition which is free. Other usefull downloads are MySQL Administrator and the MySQL Query Browser. For connecting to the MySQL server from .NET applications you also need MySQL Connector/Net 1.0

Installation of these is fairly straightforward as they all have a decent installer program. I always selected the complete installation.

Creating a database and table

As stated in the intro, this will be a simple NHibernate application, so we will create a database with a single table. This table will simply have a primary key field of type integer and a second data field of type varchar. For the primary key we will let MySQL create the key, so we will enable the ‘identity’ property.

So let’s start doing this: from the windows start-menu open the MySQL Command Line Client. After entering the password a DOS window will open and you can start entering SQL commands.

To create the database enter the following

CREATE DATABASE `nhibernate_test`;

If everything went well, MySQL will confirm with following message:

Query OK, 1 row affected (0.04 sec)

(The duration of the command can of course differ on your computer)

Now we need to create the table. Enter following line at the MySQL command prompt:

CREATE TABLE `nhibernate_test`.`helloworld` (`Id` int(10) unsigned NOT NULL auto_increment, `Message` varchar(45) NOT NULL default '', PRIMARY KEY (`Id`));

If everything went well, MySQL will confirm with following message:

Query OK, 0 rows affected (0.33 sec)

(Again, the duration of the command can of course differ on your computer)

Finally, lets add some data:

INSERT INTO `nhibernate_test`.`helloworld` (`Message`) VALUES ('Hello to the world');

If everything went well, MySQL will confirm with following message:

Query OK, 1 row affected (0.08 sec)

(The duration of the command …)

If you followed the instructions correctly, you should see something like the following in the MySQL Command Line Client :

mysqlconsole.jpg

Now the database is ready, so lets access it using NHibernate.

Creating an NHibernate application

To create the appllication, do the following:

  1. Create a console C# application using SharpDevelop. Make sure its name is “HelloWorld”.
  2. Add a reference to NHibernate.dll
  3. Create a C# file with the name MainClass.cs and copy following code into it:
    using System;
    using System.Collections;
    using NHibernate;
    using NHibernate.Cfg;
    namespace TheApp
    {
    class MainClass
    {
    public static void Main(string[] args)
    {
    Configuration config;
    config =
    new Configuration();
    config.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
    config.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MySQLDialect");
    config.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.MySqlDataDriver");
    config.SetProperty(NHibernate.Cfg.Environment.ConnectionString, "Server=localhost;Database=nhibernate_test;User ID=root;Password=root;CharSet=latin1");
    config.AddAssembly("HelloWorld");
    ISessionFactory factory;
    factory = config.BuildSessionFactory();
    ISession session = null;
    IList messages = null;
    try
    {
    session = factory.OpenSession();
    messages = session.CreateCriteria(typeof(TheData.MessageProvider)).List();
    Console.WriteLine("NofMessages:{0}\n",messages.Count);
    foreach(TheData.MessageProvider aMessage in messages)
    {
    Console.WriteLine("Id:{0} - Message:{1}", aMessage.Id, aMessage.Message);
    }
    session.Close();
    }
    catch (Exception ex)
    {
    session.Close();
    }
    }
    }
    }
  4. Create another C# file with the name MessageProvider.cs and copy following code into it:using System;
    namespace TheData
    {
    public class MessageProvider
    {
    private int id;
    private string message;
    public MessageProvider()
    {
    }
    public int Id
    {
    get { return this.id; }
    set { this.id = value; }
    }
    public string Message
    {
    get { return this.message; }
    set { this.message = value; }
    }
    }
    }
  5. Create an xml file (make sure the extension is “.hbm.xml” !), set its build action to “embedded resource” and copy following xml-tree into it:<?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" default-access="property">
    <class name="TheData.MessageProvider, HelloWorld" table="helloworld">
    <id name="Id">
    <generator class="identity" />
    </id>
    <property name="Message"/>
    </class>
    </hibernate-mapping>
  6. Compile the combine, open a console window and execute the program. You should see something like this:
    ConsoleApp

So, what’s going on?

After compiling and running the program you can see that the application automagically retrieves the data from the database, without you writing any database accessing code. What is happening here?

The class MessageProvider is a plain old C# object. It has a default constructor and all of its data members are implemented using properties. This is the class from which instances will be stored in our database. We will have to tell NHibernate how to store the properties of this class into the table in our database.

Enter the XML-file. The XML-file provides following information to NHibernate:

  1. Which class maps to which table. This is done using the “class” tag. Its attributes are “name” which provides the full name of the class (that is, namespaces and classname) and the assemblly in which it resides, and “table” which provides the name of the table.
  2. Which properties map to what column. In our example this is done using the “id” and “property” tags. The “property” tag identifies the ordinary data members of your object. In order for NHibernate to know which class property to map to what table column, we must provide both pieces of data. Because my goal was to create the most simple application, I named my table-columns equal to my class properties, which allows me to ommit the column names in my mapping file. That is why you see only “name” attributes and no “column” attributes. By ommiting the “column” attribute you tell NHibernate: “I’m using the same name for my properties and my columns”.
  3. The “id” tag also identifies the properties that will be used to identify an instance of the data in your application. It maps the primary key of your table. There are various ways to generate primary keys and the strategy used is configured through the “generator” tag. We use a simple identity type of column.

Finally, we must configure NHibernate to use our database and this mapping file. We must also tell it where to find the mapped classes. Most of this is done in our Main() method.

There are severall ways to provide the mapping files but the most simple is to include them in the assembly as an embedded resource. By using the extension hbm.xml NHibernate will be able to locate them automatically in the assembly.

The connection to our database is described in several calls to the SetProperty method of the Configuration object. We must tell NHibernate to use MySQL, and to which database it has to connect. The NHibernate Wiki provides a sample connection string, but that has a CharSet option which has to be equal with that of your database.

Telling where the class implementations reside is done by calling the AddAssembly() method of the Configuration object with the name of our assembly. In our case this is the name of our executable (which is why I asked you to name your SharpDevelop combine “HelloWorld”. That name is automatically the name of your executable). With this, you effectively tell NHibernate: “You can find the according class implementations in this assembly”.

So, where are we now? Well, we have a class, of which the instances will be saved in a database, we have a mapping of this class to our table in the database and we have told NHibernate where to find the database, the mapping and the class. Looks like we’re ready to start using all this to get some data out of the database (remember we actually stored some data in it during the setup).

To be able to do something with NHibernate, we must first create a session. This is done by creating a sessionfactory from the configuration and retrieving a session from this factory. For data retrieval we need to specify what class we want to retrieve. This is done by creating a criteria object from the session object and specifying the type of the objects you want to retrieve. Finaly we retrieve the stored objects by calling the List() method on the criteria object and iterate over its members.

Well, that’s it. Hope you got something from it. All positive critique is welcome, so let me know what you think. Usinh this blog it is impossible to include attachments other than images, so I can not provide the sample code for downloading. In a next post I hope to expand on performing basic CRUD operations in NHibernate.

Advertisements

18 thoughts on “NHibernate Part 1: Hello World with NHibernate

  1. Thanks for a very good tutorial! Just the essentials, I like that!

    I’ve been struggling with the much praised Justin Gethland tutorial for a day, but there’s just so much code before anything works. (And when it doesn’t it is not easy to find out why.) This is just what I needed to feel I grasp what I’m doing!

    I most probably will continue with the other parts in your series.

  2. Hi Daniel,

    thanks for the positive response.

    I wanted to make a tutorial which demonstrates the basics of mapping, without obscuring the code with best practices or hiding behind an interface. Looks like I succeeded.

    Hope you enjoy the rest of the series.

  3. Hi,
    Its a very good tutorial to start of with , but I am facing a problem with it . It is throwing a exception while loading the assembly at the line
    “config.AddAssembly(“HelloWorld”);” and I am not able to proceed further.

  4. Hi,
    I tried your tutorial, it is really perfect but i am getting an error all the time!

    HelloWorld.XMLFile.hbm.xml(2,2): XML validation error: Could not find schema information for the element ‘urn:hibernate-mapping-2.0:hibernate-mapping’.

    And it shows from the code:
    config.AddAssembly(“HelloWorld”);

    what can be the problem?
    Thanks!

  5. Could it be you are using some 2.0 version of NHibernate? I used the 1.0 version, so maybe… I’ve stopped experimenting with NHibernate because the project we we’re working on got canceled and currently I do not have a development environment wich alows me to experiment. Maybe someone else could be of assistance.

  6. Hi,
    I get an error i have already encounter without solutions. I’m pretty sure you could help me :

    Could not create the driver from NHibernate.Driver.MySqlDataDriver

    I’m very disturb with this because i would really use nhibernate with MySql but there is certainly something wrong in my understanding 😉

    Gilles M

  7. nice startup tutorial. I think the only changes are
    change xmlns=”urn:nhibernate-mapping-2.0″ to xmlns=”urn:nhibernate-mapping-2.2″

    and make properties virtual in MessageProvider class

  8. if you try to copy your xml from here to a real xml file then u cant work it. This is a issue for me because there isnt a example for Nhibernate on internet to find and work as the publishers of the examples said.

  9. Thanks, I’m new to blogging, could do with some advice.. Great informative site, a great read. Keep up the good work all, Will return shorlty for your latest updates. Cheers…

  10. This error pops up

    The ProxyFactoryFactory was not configured.
    Initialize ‘proxyfactory.factory_class’ property of the session-factory configuration section with one of the available NHibernate.ByteCode providers.
    Example:
    NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu
    Example:
    NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle

    I’m using NHibernate 2.1.2

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