Quickstart with NHibernate for Dummies like me.

First of all read the not-so-QuickStart page from Hibernate.org. Anohter interesting source of information is Baccus.
After spending an half-a-day to make it work, I collected here some issues and fixes.
As you can read in the comments in the same page, the QuickStart tutorial doesn’t work out of the box. I think there are different issues: the main one is that probably it’s a bit outdated vs the current NHibernate version. But the comments in that page are indeed very useful. If you have problem running the Quickstart, have a look there. Credit for many solutions goes to the guys that posted their fixes on that page.

Anyway I’m quite green in C# so don’t take my words for granted. Nevertless, it now works fine for me. I don’t claim it’s the best or the correct way to use NHibernate. Tutorial examples just didn’t work for me, and now it works. Moreover, I won’t cover the entire tutorial, but I will just underline the differences.

Tools needed:
NHibernate
Visual Studio (VS2008 express worked for me).
.NET framework (2.0).
A database (I use Windows MS SQL 2005 express bundled with VS2008 Express). If you use another database your mileage may vary, but should not vary that much (or what’s the point of using an ORM?)
(optional) Microsoft SQL Server Management Studio Express (MSSMSE)

I assume you already created the database named NHibernate and the table users. For starters, you may use Microsoft SQL Server Management Studio Express to create the database and the table.
Creating the project, I start a Visual C# console application, named QuickStart.
I save, and since I have installed also Microsoft SDK 2008, so I go to Project->QuickStart properties and change the target .NET framework to 2.0 (default is 3.5, it should work, but I don’t want to know). I also set the entry point to QuickStart.program.
Now I create the user.cs class. Have a look at it, since it’s slighly different from the one presented in the tutorial:

using System;
namespace NHibernate.Examples.QuickStart{public class User{

private string id;

private string userName;

private string password;

private string emailAddress;

private DateTime lastLogon;public User()

{

}

public virtual string Id

{

get { return id; }

set { id = value; }

}

public virtual string UserName

{

get { return userName; }

set { userName = value; }

}

public virtual string Password

{

get { return password; }

set { password = value; }

}

public virtual string EmailAddress

{

get { return emailAddress; }

set { emailAddress = value; }

}

public virtual DateTime LastLogon

{

get { return lastLogon; }

set { lastLogon = value; }

}

}}

As you can see, I have the property virtual on my methods. The reason is briefly outlined here: http://forum.hibernate.org/viewtopic.php?t=960004.

All classes and collections are now lazily loaded by default (i.e. the default setting for the lazy attribute is now “true”). To aid in the transition, classes used for lazy loading are now validated and an error is thrown if any of their public members are not virtual. This validation can be disabled.

I’m not goind to disable anything, so we just add the property virtual to our methods. If you don’t do this, you will get a similar exception:
{“The following types may not be used as proxies:\nNHibernate.Examples.QuickStart.User: method get_EmailAddress should be virtual\nNHibernate.Examples.QuickStart.User: method set_EmailAddress should be virtual”}

Now for the class mapping file. Mine it’s also a bit different.

There are a bit of important changes here. In the first place, <hibernate-mapping xmlns=”urn:nhibernate-mapping-2.0″> is going to give you a similar error: {“QuickStart.User.hbm.xml(2,2): XML validation error: Could not find schema information for the element ‘urn:nhibernate-mapping-2.0:hibernate-mapping’.”} Then, we changed here: <class name=”NHibernate.Examples.QuickStart.User, NHibernate.Examples” table=”users”> with the assembly name with our assembly name (QuickStart). Finally, we changed the table name with: table=”[NHibernate].[dbo].[users]” as described here. Failing to change this will get you such an error: {“could not insert: [NHibernate.Examples.QuickStart.User#joe_cool][SQL: INSERT INTO users (Name, Password, EmailAddress, LastLogon, LogonId) VALUES (?, ?, ?, ?, ?)]”} Update: as long as you provide the correct database in the app.config key: <add key=”hibernate.connection.connection_string” value=”Server=.\SQLEXPRESS;initial catalog=nhibernate;Integrated Security=SSPI”/> there’s no need to change table=”users”. Note: Don’t forget to set the Build Action from “Content” to “Embedded resource” in the Properties dialog for the User.hbm.xml file, or it won’t be added to the assembly, and you’d get this: {“Unknown entity class: NHibernate.Examples.QuickStart.User”} Now for the Program.cs file:

using System;using System.Collections.Generic;

using System.Text;

using NHibernate;

using NHibernate.Cfg;

 using NHibernate.Examples.QuickStart;

namespace QuickStart{

class Program

{

static void Main(string[] args)

{

Configuration cfg = new Configuration();

             cfg.AddAssembly("Quickstart");

ISessionFactory factory = cfg.BuildSessionFactory();

ISession session = factory.OpenSession();

ITransaction transaction = session.BeginTransaction();

User newUser = new User();

newUser.Id = "joe_cool";

newUser.UserName = "Joseph Cool";

newUser.Password = "abc123";

newUser.EmailAddress = "[email protected]";

newUser.LastLogon = DateTime.Now;            // Tell NHibernate that this object should be saved

session.Save(newUser);

// commit all of the changes to the DB and close the ISession

transaction.Commit();

session.Close();

}

}

}

it’s very similar with the exception of the assembly name (QuickStart, in this case) .
I also added an using NHibernate.Examples.QuickStart; to stop him complaining like:

The type or namespace name ‘User’ could not be found (are you missing a using directive or an assembly reference?)

Finally, let’s go to the app.config file.
Did not change a lot, just the connection string.

Of course, I use MS SQL Express, so I had to change it a bit. If integrated security does not work for you, the usual approach user-password may be useful (of course you need a valid mssql user), and change your Server value accordingly to the correct MSSQL instance:localhost may work for non-express MSSQL version. The app.config suggested in the tutorial used to give me this sort of error:

{“cannot open connection”}{“An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server)”} .
I hope it will be useful for someone. I spent an half a day going through all these issues, eventually thinking about dropping NHibernate, but now I can start working.
I you wish, I made up my code in a little QuickStart.zip project. It should work with Visual Studio 2008.
NHibernate project for QuickStart Tutorial

4 thoughts on “Quickstart with NHibernate for Dummies like me.

  1. I’m sorry: it was still pointing to the old blog, and I guess the file got lost in the migration. I can’t seem to find it.
    Thanks for pointing out.

  2. attention,
    You can not use table ‘User’ – it is not possible in SQL.
    ‘Users’ is ok, but ‘user’ is forbiden.
    Some one, lik me, could named his table becaouse of class name is User

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