7 min read

NHibernate is an open source object-relational mapper, or simply put, a way to rapidly retrieve data from your database into standard .NET objects. This article teaches you how to create NHibernate sessions, which use database sessions to retrieve and store data into the database.

In this article by Aaron B. Cure, author of Nhibernate 2 Beginner’s Guide we’ll talk about:

  • What is an NHibernate session?
  • How does it differ from a regular database session?
  • Retrieving and committing data
  • Session strategies for ASP.NET

(Read more interesting articles on Nhibernate 2 Beginner’s Guide here.)

What is an NHibernate session?

Think of an NHibernate session as an abstract or virtual conduit to the database. Gone are the days when you have to create a Connection, open the Connection, pass the Connection to a Command object, create a DataReader from the Command object, and so on.

With NHibernate, we ask the SessionFactory for a Session object, and that’s it. NHibernate handles all of the “real” sessions to the database, connections, pooling, and so on. We reap all the benefits without having to know the underlying intricacies of all of the database backends we are trying to connect to.

Time for action – getting ready

Before we actually connect to the database, we need to do a little “housekeeping”. Just a note, if you run into trouble (that is, your code doesn’t work like the walkthrough), then don’t panic. See the troubleshooting section at the end of this Time for action section.

  1. Before we get started, make sure that you have all of the Mapping and Common files and that your Mapping files are included as “Embedded Resources”. Your project should look as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  2. The first thing we need to do is create a new project to use to create our sessions. Right-click on the Solution ‘Ordering’ and click on Add | New Project.

    Creating a NHibernate session to access database within ASP.NET

  3. For our tests, we will use a Console Application and name it Ordering.Console. Use the same location as your previous project.

    Creating a NHibernate session to access database within ASP.NET

  4. Next, we need to add a few references. Right-click on the References folder and click on Add Reference. In VB.NET, you need to right-click on the Ordering.Console project, and click on Add Reference.

    Creating a NHibernate session to access database within ASP.NET

  5. Select the Browse tab, and navigate to the folder that contains your NHibernate dlls. You should have six files in this folder. Select the NHibernate.dll, Castle.Core.dll, Castle.DynamicProxy2.dll, Iesi.Collections.dll, log4net.dll, and NHibernate.ByteCode.Castle.dll files, and click on OK to add them as references to the project.

    Creating a NHibernate session to access database within ASP.NET

  6. Right-click on the References folder (or the project folder in VB.NET), and click on Add Reference again. Select the Projects tab, select the Ordering.Data project, and click on OK to add the data tier as a reference to our console application.

    Creating a NHibernate session to access database within ASP.NET

  7. The last thing we need to do is create a configuration object. We will discuss configuration in a later chapter, so for now, it would suffice to say that this will give us everything we need to connect to the database. Your current Program.cs file in the Ordering.Console application should look as follows:

    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Ordering.Console
    {
    class Program
    {
    static void Main(string[] args)
    {
    }
    }
    }

    Or, if you are using VB.NET, your Module1.vb file will look as follows:

    Module Module1
    Sub Main()
    End Sub
    End Module

  8. At the top of the file, we need to import a few references to make our project compile. Right above the namespace or Module declarations, add the using/Imports statements for NHibernate, NHibernate.Cfg, and Ordering.Data:

    using NHibernate;
    using NHibernate.Cfg;
    using Ordering.Data;

    In VB.NET you need to use the Imports keyword as follows:

    Imports NHibernate
    Imports NHibernate.Cfg
    Imports Ordering.Data

  9. Inside the Main() block, we want to create the configuration object that will tell NHibernate how to connect to the database. Inside your Main() block, add the following code:

    Configuration cfg = new Configuration();
    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionProvider,
    typeof(NHibernate.Connection.DriverConnectionProvider)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect,
    typeof(NHibernate.Dialect.MsSql2008Dialect)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver,
    typeof(NHibernate.Driver.SqlClientDriver)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString,
    “Server= (local)SQLExpress;Database=
    Ordering;Trusted_Connection=true;”);

    cfg.Properties.Add(NHibernate.Cfg.Environment.
    ProxyFactoryFactoryClass, typeof
    (NHibernate.ByteCode.LinFu.ProxyFactoryFactory)
    .AssemblyQualifiedName);

    cfg.AddAssembly(typeof(Address).AssemblyQualifiedName);

    For a VB.NET project, add the following code:

    Dim cfg As New Configuration()
    cfg.Properties.Add(NHibernate.Cfg.Environment. _
    ConnectionProvider, GetType(NHibernate.Connection. _
    DriverConnectionProvider).AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect, _
    GetType(NHibernate.Dialect.MsSql2008Dialect). _
    AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver, _
    GetType(NHibernate.Driver.SqlClientDriver). _
    AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString, _
    “Server= (local)SQLExpress;Database=Ordering; _
    Trusted_Connection=true;”)

    cfg.Properties.Add(NHibernate.Cfg.Environment. _
    ProxyFactoryFactoryClass, GetType _
    (NHibernate.ByteCode.LinFu.ProxyFactoryFactory). _
    AssemblyQualifiedName)

    cfg.AddAssembly(GetType(Address).AssemblyQualifiedName)

  10. Lastly, right-click on the Ordering.Console project, and select Set as Startup Project, as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  11. Press F5 or Debug | Start Debugging and test your project. If everything goes well, you should see a command prompt window pop up and then go away. Congratulations! You are done!
  12. However, it is more than likely you will get an error on the line that says cfg.AddAssembly(). This line instructs NHibernate to “take all of my HBM.xml files and compile them”. This is where we will find out how well we handcoded our HBM.xml files.

    The most common error that will show up is MappingException was unhandled. If you get a mapping exception, then see the next step for troubleshooting tips.

    Creating a NHibernate session to access database within ASP.NET

  13. Troubleshooting: NHibernate will tell us where the errors are and why they are an issue. The first step to debug these issues is to click on the View Detail link under Actions on the error pop up. This will bring up the View Detail dialog, as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  14. If you look at the message, NHibernate says that it Could not compile the mapping document: Ordering.Data.Mapping.Address.hbm.xml. So now we know that the issue is in our Address.hbm.xml file, but this is not very helpful. If we look at the InnerException, it says “Problem trying to set property type by reflection“. Still not a specific issue, but if we click on the + next to the InnerException, I can see that there is an InnerException on this exception.

    The second InnerException says “class Ordering.Data.Address, Ordering.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null not found while looking for property: Id“.

    Now we are getting closer. It has something to do with the ID property. But wait, there is another InnerException. This InnerException says “Could not find a getter for property ‘Id’ in class ‘Ordering.Data.Address'”. How could that be? Looking at my Address.cs class, I see:

    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Ordering.Data
    {
    public class Address
    {
    }
    }

    Oops! Apparently I stubbed out the class, but forgot to add the actual properties. I need to put the rest of the properties into the file, which looks as follows:

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Ordering.Data
    {
    public class Address
    {
    #region Constructors
    public Address() { }
    public Address(string Address1, string Address2, string
    City, string State, string Zip)
    : this()
    {
    this.Address1 = Address1;
    this.Address2 = Address2;
    this.City = City;
    this.State = State;
    this.Zip = Zip;
    }
    #endregion
    #region Properties
    private int _id;
    public virtual int Id
    {
    get { return _id; }
    set { _id = value; }
    }
    private string _address1;
    public virtual string Address1
    {
    get { return _address1; }
    set { _address1 = value; }
    }
    private string _address2;
    public virtual string Address2
    {
    get { return _address2; }
    set { _address2 = value; }
    }
    private string _city;
    public virtual string City
    {
    get { return _city; }
    set { _city = value; }
    }
    private string _state;
    public virtual string State
    {
    get { return _state; }
    set { _state = value; }
    }
    private string _zip;
    public virtual string Zip
    {
    get { return _zip; }
    set { _zip = value; }
    }
    private Contact _contact;
    public virtual Contact Contact
    {
    get { return _contact; }
    set { _contact = value; }
    }
    #endregion
    }
    }

  15. By continuing to work my way through the errors that are presented in the configuration and starting the project in Debug mode, I can handle each exception until there are no more errors.

What just happened?

We have successfully created a project to test out our database connectivity, and an NHibernate Configuration object which will allow us to create sessions, session factories, and a whole litany of NHibernate goodness!

LEAVE A REPLY

Please enter your comment!
Please enter your name here