Adventures in NHibernate – Part 1 (Configuration)

by Mikael Henriksson 25. July 2009 15:09

To start with I’d like to state (and people might shoot me for this) that NHibernate has as many issues as any other framework I’ve laid my hands on. As I said before it has it’s pro’s and con’s.  In the following examples I will be using FluentNhibernate for the simple reason it is so simple to use :)

To use NHibernate in any form successfully you would need a whole bunch of managers. I will start with the configuration and I’ll try being as DRM (don’t repeat myself)  as I can.

They sure made stuff fluent with FNH. And in NHibernate 2.1 the configuration part is fluent. What does a fluent API mean? See Alex James blog poston the subject! The fluent part is all well but only to a certain extent. After that I want to have a bit better control over things for obvious reasons. With FNH you can configure your data access and just return a session to use for saving, retrieving or deleting data. This is fine in a simple example but I’d like  to have a more multipurpose configuration and what if the application grows on me. I have had a look at the Sharp-Architecture and it looks very nice but what is the fun of using a complete framework? I want to create my own :)

The class for handling the configuration will be named ConfigurationManager is there a better name?
It will just return an NHibernate configuration for starters but I’ll add a couple of extra methods to it.

internal static class ConfigurationManager
{
	private static readonly string PathToSqlLiteDb =
		System.Configuration
			  .ConfigurationManager.AppSettings["PathToSqlLiteDb"];

	internal static Configuration GetConfiguration()
	{
		return GetFluentConfiguration().BuildConfiguration();
	}

	internal static void UpdateSchema()
	{
		GetFluentConfiguration().ExposeConfiguration(BuildSchema);
	}

	private static void BuildSchema(Configuration config)
	{
		if (File.Exists(PathToSqlLiteDb))
		{
			new SchemaUpdate(config);
		}

		new SchemaExport(config).Create(true, true);
	}

	private static FluentConfiguration GetFluentConfiguration()
	{
		FluentConfiguration fluentConfig = Fluently.Configure()
			.Database(SQLiteConfiguration.Standard.UsingFile(PathToSqlLiteDb))
			.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>());

		return fluentConfig;
	}
}

I feel this is a pretty good start. Now I’ll see if I can get a grip on the session management. Since this is a web application I suppose it will be a bit more difficult. I somehow need to create a session per user if I am not mistaken.

Tags:

Fluent NHibernate

Table-Per-Class inheritance with Fluent NHibernate

by Mikael Henriksson 23. July 2009 08:59

First of all I am an Entity Framework dude. Don’t worry I’m not going to convert BUT my boss and friend has a history of being an expert DBA and those guys have their own take own naming columns and at a recent project we were working on I realized it was going to be way to much work customizing the EF model every time I needed to regenerate it and the only thing I could think of was fluent nhibernate(besides T4 template maybe but imagine the work to have T4 do the whole generation for you).

I of course instantly joined the mailing list which is one of the best mailing lists I’ve ever joined. I even managed to help a guy once but that’s not why I am writing. My first try on Fluent was not a success, my second try was semi successful. Then I have the third try in a bogus project I am doing just for fun. Second time around with all the funny column names with under_scores etc I had no problems mapping to an existing database but when I try to do the same at home for my bogus project it fails…. LOL! No exceptions nothing even happens. I created a unit test to setup a sqlite db and nothing. So I switch over from my fluent mappings to AutoMappings and voila there is the Db with inheritance etc. My take on that is that I actually created a pretty good class structure but it took some time to figure out the Fluent Part. There is a lot of information about how to map fluently but hardly any information about how inheritance is supposed to work and reading the NHibernate documentation about sub-classing doesn't help much either. Time to ask the mailing list. It’s mostly James that answers and he answers most times of the day. I got a reply at 7 something in the morning!! With version 1 only a few weeks away this might be old news by then but since I could not find any information about JoinedSubClass I thought I’d post it still. There is a new feature called SubClassMap<T> coming for FNH 1.0 but that is pretty far away from NHibernate-JoinedSubClass-XmlMapping so I thought I’d post it here for future reference.

person

As you can see Contact inherits from Person. The reason is that I don’t want users to have to type in the names of people who organizes or helps out with tournaments and I really don’t want them to have to fill out contact information for persons who is just organizing and helping out and if I ever have a look in the person table I will go crazy if I see a lot of empty information for contact_address_street_one and so on and so forth.

internal class PersonMap : ClassMap<Person>
{
	public PersonMap()
	{
		WithTable("persons");

		Id(x => x.Id, "person_id");
		Map(x => x.FirstName, "person_first_name");
		Map(x => x.LastName, "person_last_name");
		Map(x => x.CreatedAt, "created_at");

		JoinedSubClass<Contact>("person_id", MapContact);
	}

	private static void MapContact(JoinedSubClassPart<Contact> p)
	{
		p.WithTableName("contacts");
		p.Map(x => x.Email, "contact_email");
		p.Map(x => x.Phone, "contact_phone");
		p.Map(x => x.Mobile, "contact_mobile");

		p.Component(x => x.Address, 
		c =>
			{
				c.Map(x => x.StreetOne, "address_street_one");
				c.Map(x => x.StreetTwo, "address_street_two");
				c.Map(x => x.Zip, "address_zip");
				c.Map(x => x.City, "address_city");
				c.Map(x => x.Country, "address_country");
			});

		p.References(x => x.ContactType)
			.LazyLoad()
			.Cascade.All()
			.ColumnName("contact_type_id");
	}
}

That should on SchemaExport generate a table-per-subclass type of schema. In the future it will get even easier. Fluent is becoming an intuitive interface towards NHibernate. Gone is the need for XML mappings. If I am not mistaken NHibernate will become something totally different in the future everything is becoming Fluent even the configuration. What I miss in the Entity Framework is there with Fluent but then again I miss some things from Entity Framework when I work on NHibernate. I guess they will never really compete on the same level. And also things are changing more rapidly for NHibernate since they release more often :) It can however not hurt to learn both!

Tags:

Fluent NHibernate