NHibernate Part 2: CRUD 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

In the previous installment in this series of articles about NHibernate I explained a simple Hello World application which uses NHibernate to read messages from a database.

In this article we will learn how to perform basic CRUD operations. The CRUD acronym stants for the 4 operations which can be performed on data stored on a medium:

  1. Create
  2. Read
  3. Update
  4. Delete

We will continue to work with the database created in Part 1. All sample output also assumes you have excercised Part 1.

Creating the application

To create the sample application, execute following steps:

  1. Create a console application using SharpDevelop named NHibernateCRUD. The name is important (See Part 1 for the reason).
  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 NHibernateCRUD
    {
    class TheApp
    {
    static void Main(string[] args)
    {
    Configuration config;
    ISessionFactory factory;

    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(“NHibernateCRUD”);

    factory = config.BuildSessionFactory();

    ISession session = null;
    IList messages = null;
    ITransaction transaction = null;

    try
    {
    session = factory.OpenSession();
    transaction = session.BeginTransaction();

    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);
    }

    // Create
    TheData.MessageProvider newMessage = new TheData.MessageProvider();
    newMessage.Message = “Hello brave new world.”;
    session.Save(newMessage);

    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);
    }

    //Read
    string querySting = “from TheData.MessageProvider as msgProv where msgProv.Id=” + newMessage.Id;
    IQuery query = session.CreateQuery(querySting);
    messages = query.List();
    foreach(TheData.MessageProvider aMessage in messages)
    {
    Console.WriteLine(“Id:{0} – Message:{1}”, aMessage.Id, aMessage.Message);
    }

    //Update
    ((TheData.MessageProvider)messages[0]).Message = “Hello to the brave new world”;
    session.Save(messages[0]);

    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);
    }

    //Delete
    session.Delete(messages[0]);

    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);
    }

    transaction.Commit();
    session.Close();
    }
    catch (Exception ex)
    {
    transaction.Rollback();
    session.Close();
    }
    }
    }
    }

  4. Copy the file MessageProvider.cs from the NHibernate Part 1 article.
  5. Copy the MessageProvider.hbm.xml file from the NHibernate Part 1 article and set it’s build action to “embedded rersource”.
  6. Compiling the combine and running the application in a console window should show someting like this:
    NHibernateCRUD

Explaining the code

For an explanation of setting up the connection with NHibernate and what the meaning of the tags in the mapping file are, you can read Part 1 of this article.

Once we have a sesson object we start a transaction on that session. That way, if anything goes wrong during our CRUD manipulations, we can rollback all changes and keep the database consistant.

Then the first lines are a simple repeat of what was done in Part 1 of the article, so you can look there for an explanation.

Then, the new stuff begins:

Create:

Creating a new entry in the database requires two steps; The first step is to create a new object for addition, and the second step is actually adding the new object to the database. The creation step is the familiar creation of an object as you know it in C# using the new-operator. After creating the object you set its properties. To save the newly created object, you feed it to the Save method of the session object. Internally NHibernate uses info in the mapping file to create an SQL string which is then executed on your database, effectively storing the object in the database. Notice that NHibernate will automatically fill the identity property of your saved object with the value from the database.

Read:

Reading entries from a database can be done in a few ways. You allready now one of it from Part 1. This retrieved all objects of a certain type. Now, we will rerieve a specific object of a certain type using some criteria for its properties. This is done with the NHibernate variation of SQL: HQL or Hibernate Query Language:

    1. First, tell the type of obect you want to read: “from {typename} as {alias} “
    2. Then, tell the criteria you want to object(s) to match: “where {criteria}”, in which criteria is of the form “{propertyname}={value}”

From this query string, a query object is created which is then used to read the objects from the database. Behind the scenes, NHibernate will create the appropriate SQL to get the objects you desire.

Update:

Updating must be about the simplest thing to do. Just save your object. Again, behind the scenes NHibernate creates an appropriate SQL statement which it executes against your database, effectively updating it.

Delete:

Deleting an object from the database is as simple as executing the Delete method of the session object an feeding it the object you want removed from the database. Again, behind the scenes NHibernate creates to necessary SQL to delete the appropriate record from the database.

Now, commiting the transaction will effectively save our changes to the database.

So, this is it for simple CRUD operations. In the next installments I will explain in more detail the mapping possibilities of NHibernate. See you later.

4 thoughts on “NHibernate Part 2: CRUD with NHibernate

  1. Do you have a better delete operation which does not require reading the object from the database first? Delete using the query is not the solution here because it is not hibernate way of manipulating objects.

Leave a reply to Imad Cancel reply