NHibernate O/R Mapper: Part 2

In a previous post I talked about my first impressions of NHibernate. Not a whole lot has changed since then, except I have learned a lot more. But, I said I would discuss what I didn’t like about NHibernate so here it goes.

Session Management

The biggest thing that I don’t like is the session management aspect. Although I have come to understand why NHibernate sessions are so valuable and critical to its functionality, it doesn’t stop the fact that persistent objects are tied to a single database. For a project that follows the patterns and practices set forth in ivory towers, this works great. All business entities are stored in a database in 6th normal form and everyone is happy. Well, when working with legacy and enterprise systems, that usually isn’t the case. There are many different databases that are used and objects are stored across a variety of them.

In order to get my system to use NHibernate, the first challenge was incorporating multiple sessions. A session is basically a connection to a single database that manages persistent objects. This article describes a really complex way to accomplish it, but all you really need to pay attention to is the NHibernateSessionModule and NHibernateSessionManager. Using the outline described in the article, I successfully got multiple sessions to work fairly painlessly.

The second challenge was storing a persistent object in multiple database. Since persistent objects in NHibernate can’t span multiple sessions, some data massaging has to be performed. As I see it, there are two possibilities for storing an object in multiple database.

  1. Different objects for each database with type conversion operators
  2. The same object for all databases with extra session logic

The latter is obviously easier from a domain model perspective, but not from an implementation perspective. For a persistent object from one session to be stored in another session, all references must be removed from the session. This means unproxying the object and unpersisting any collections contained within the object. Looking through the NHibernate source code, I was able to accomplish this with only a few lines of code.

Setup & Documentation

Most of the getting started guides for NHibernate are no where near complete or up-to-date. It took a couple days to get my environment up and running. This isn’t really a problem with the library itself, but is still a problem for first time users. In all reality, there seems to be a lack of documentation in general. Three example mappings in the documentation is no where near enough for what is marketed as an enterprise ORM solution.

Conclusion

NHibernate is awesome. Even with these minor issues, it is one of the greatest tools for web development I have ever used. I hope that the development of this library continues to improve, and hopefully some of these issues will be resolved.

NHibernate O/R Mapper: Part 1

As most of you know, the data access layer is my favorite application layer to work with. For a while, I worked on my own active record implementation in PHP. After switching to .NET, my outlook has strayed away from the active record pattern though. I like using business entity objects that have no coupling to a database. Instead, I use an object/relational mapper to translate from business entity to persisted database object.

At first, I started working on my own implementation again, which provided a simple, in code, mapping technique. I quickly realized that mapping business entity relationships wasn’t easy though. After a couple hours of staring at my monitor hoping I could come up with an elegant solution, I decided to look at some 3rd party mappers. I had heard about NHibernate before and decided to give it a shot.

I spent about two days prototyping part of my database in NHibernate and my first impression is wow. Everything I could think of adding in an o/r mapper exists in NHibernate. Lazy loading, relationships, inheritance, component mapping, and so much more is possible. Over the past few weeks, my entire data access layer has been converted to NHibernate with overwhelming success. Like any library, it has its own quarks, but for the most part it speeds up development time while adding lots of power to my applications. I would recommend it to anyone.

NHibernate uses XML documents or .NET attributes to map an entity class to a database. I never thought I would use XML again after painful VB6 experiences, but I decided to give it another shot. To my surprise, I loved it. It allows for really clean separation of the database and code, which basically means cleaner code and a happier Brian. The only really annoying part of NHibernate is session management, but I’ll save that for part 2.

IIS 6.0 and ASP.NET 2.0 on Windows Server 2003 x64

Today, I ran into an interesting issue trying to run an ASP.NET 2.0 web application through IIS 6.0. Usually, it isn’t a problem, but since the host machine is running 64 bit windows, some issues were encountered.

The first symptom I ran into was a 503 Service Unavailable response when accessing the website from a browser. Checking the IIS error logs showed a AppOffline DefaultAppPool error description, not very helpful. The event log had a better message:

ISAPI Filter ‘C:\Program Files (x86)\Common Files\Microsoft Shared\Web Server Extensions\50\bin\fpexedll.dll’ could not be loaded due to a configuration problem. The current configuration only supports loading images built for a x86 processor architecture. The data field contains the error number. To learn more about this issue, including how to troubleshooting this kind of processor architecture mismatch error, see http://go.microsoft.com/fwlink/?LinkId=29349.

Googling found two related articles, one on the 503, and another on the ISAPI issue.

The solution recommended running the following command:
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1

When this command was ran, nothing was fixed. I tried running the inverse, and setting to only allow 64 bit applications, and it worked.
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 0

Thoughts on ASP.NET

Originally, I had planned on blogging about each major ASP.NET 2.0 feature independently. Themes, Membership, Roles, ADO.NET, Controls, and many more were already on my list, but I began to realize I had the same thoughts on most of them. Although I still plan to give a detailed review of each feature, I wanted to go ahead on voice my opinions on ASP.NET.

The Bad

ASP.NET, in my opinion, attempts to provide a RAD environment for developing new applications. DataSets, Membership, Roles, and Data-bound controls all show how ASP.NET doesn’t want the developer to waste time on mundane tasks. What I hate is the lack of flexibility with these approaches. For the same reason I dislike Rails, I dislike many of the extras ASP.NET has to offer.

For example, I don’t want to use the Membership API because I am porting an existing application to ASP.NET. Membership has a strict set properties a MembershipUser must have. This is inflexible. I don’t want to adapt my application to fit with Membership, I want Membership to adapt to my application. The same goes for many of the other tools in ASP.NET.

The Good

ASP.NET is a great foundation. It provides all the necessary tools to create a great web application. Although ASP.NET is a framework, it lets you pick the tools you need and want for your application. If you want to implement a custom authentication system, you don’t have to use Membership. If you hate DataSets, don’t use them.

For developing new Web 2.0 applications, I have no doubt that using all the built-in ASP.NET tools could greatly speed up development. For existing applications, or enterprise applications, many of the tools probably won’t work. But at least you have the option to pick and choose.