Wednesday, May 28, 2008

First impressions with NHibernate 2.0

Almost two months ago, Ayenda Rahien announced the release of the first alpha of a new generation of NHibernate. NHibernate's feature set has always been a subset of the corresponding Java equivalent, Hibernate 3.x. With the new Nhibernate 2.0 release, the team has aligned its feature set with that of Hibernate 3.2. Its almost at the same level now.

In his announcement, Ayende also stated that this alpha version was tested thoroughly in a production environment. Due to Ayende's reputation, we decided to try it as well, and I must agree, other than the initial breaking changes, we did not run into any problems yet. Since the documentation is not up to date yet, we have not started using any of the new features, and limited the upgrade to getting the existing system running with 2.0 alpha 1. Some of the more noticeable things to take into account include:

  • You cannot wrap a binding variable in a lower() function anymore. I don't know why this has changed, but you now have to call ToLower() while passing the value to the SetParameter() method of IQuery.
  • The SysCache provider is no longer part of the NHibernate distribution. You have to get it from SourceForge yourself, but getting the sources is painfully difficult without using SubVersion. For your convenience, you can get a compiled version compatible with NH2.0 alpha 1 from here.
  • The IQuery.SetParameterList method has received an overload that takes an ICollection in addition to the one that takes an array. Consequently, the compiler will start to comply about ambiguous calls. You need to explicitly specify the overload you need.
  • The ValueValueType (from the NHibernate.Type namespace) has been phased out. We used it to create a custom NHibernate type that supports storing a boolean as a J/N character (Dutch for yes and no). The best alternative is the ImmutableType.
  • The NHibernate.Expression namespace has been renamed to NHibernate.Criterion
  • We use a modified connection provider that passes some additional information to the database whenever a connection is created. It requires a few configuration settings that we made part of the <hibernate> configuration section. NH 2.0's DriverConnectionProvider changes the Configure method from a IDictionary to a generic collection, and it has become very picky of the contents of the <hibernate> section (it validates it using an XSD). We had to move our configuration data to the <appSettings> section.
  • NH 2.0 will validate all named HQL and SQL queries when it's loading the mapping files. We discovered quite a few unused queries, so that was a nice side-effect.

Another aspect that makes this new version quite interesting is that the approaching release of the ADO.NET Entity Framework (now part of Visual Studio 2008 Service Pack 1 Beta) reveals that NHibernate easily wins on the feature and flexibility level. I myself was considering moving over to the Entity Framework whenever a suitable project passed by, but after having heard of the lack of lazy-loading support and the amount of impact it has on my domain model (the generated business classes), I'm not sure anymore. Hopefully the NHibernate team will continue with the LINQ-to-NHibernate project as soon as possible. Since Ayende seems to track blog posts referring to NHibernate, he may answer this question soon enough.