Evangelizing NHibernate

I saw a post today about ORMs and how they are hard to use and maintain.  Since we saw ActiveRecord/NHibernate at Ben's talk and we're going to have more talks on ORM tools there may be questions.  I wanted to share my experience and assuage some fears about ORMs that may be holding you up from getting started..

I'm using NHibernate, which does have a learning curve, but it's not as steep as you might think.

Here are one of the criticisms mentioned:

They are not legacy system friendly meaning they are a nightmare to implement

My current project is pulling data from an Oracle 9i database with a schema and data that has been around for 10+ years. I created a few new tables for my stuff and getting set up and relating to the old stuff was painless.

The most unmaintainable thing about the system is all the business rules encapsulated in stored procedures. Fortunately once I got the gist of those rules, which are also enforced in constraints, they were a snap to implement in code.

Real nightmares

What is a nightmare is the previous app that used this data.  I found this method of the Account class used to persist new instances in that old, legacy app:

Public Function Save() As Int32
Dim MyDataAccess As New Legacy.BLL.DataAccess
Dim MyCommand As New OleDbCommand
Dim sb As New StringBuilder
sb.Append("LEGACY_ACCT_PKG.SAVE_ACCOUNT")
MyCommand.CommandText = sb.ToString

MyCommand.Parameters.Add(New OleDbParameter("pACCOUNTID", OleDbType.Numeric, 22, ParameterDirection.Input)).Value = _ID
' ... 20+ more parameters!!! horror!
MyDataAccess.isSetGlobalContext = True
MyDataAccess.RunSP("", MyCommand)
End Function

This is one of hundreds of similar CRUD methods in this app.  Not maintainable.

I don't have a save method in my class, I am using repositories.. the actual "data access" code, common to all the objects I persist is:

public virtual T Save(T entity)
{
NHibernateSession.Save(entity);
return entity;
}

To me that was very easy.  NHibernate handles things for me, I don't have to worry about 20 or 30 of the things that a user of that one old-fashioned method has to worry about. Including all that horrible ADO.NET mess.

Query languages considered harmful?

Here's another criticism:

They require an Intermediary Query Language which means extra work for the programmer

Eh... ok, extra work to learn a query language. Getting the gist of NHibernate's query language takes about 5 minutes.  If you want to explore its intricacies, take an hour to parse the relevant docs.    But writing it is pretty easy!  Here's a simple but typical example of a query to pull back all Projects that a certain Employee is a TeamMember of (think of it as populating a grid on a "My Projects" page):

from Project p join fetch p.Team t where t.Employee = ?

which generates SQL something like:

select * from project 
inner join team on project.id = team.projectid
where team.emplid = :p

Still, there's no requirement that you learn HQL. There are other ways to query: using the Criteria API, straight SQL and in code.  It's okay to decide to avoid pain.

Pain relief

If religion is opium for the masses then object relational mapping would be like Aspirin in the programming world . Not powerful enough to get any programmer high and makes programming easier for about four hours, then real sedation is required to mask the pain. They have even been likened to an unwinnable war in South-East Asia.

This has not been my experience.  What causes me pain is having to deal with the data access myself, or to have queries in my code-behind or worse, in the markup.  It's painful to worry about columns and constraints instead of conceptual relationships and meaning.

Here are some NHibernate resources I found to be really helpful:

Critical to read the documentation
Billy McCafferty's NHibernate Best Practices (I read it four times and it keeps getting better)
Ben Scheirman's NHibernate screencast (very good tips in here)
Setting up NHibernate mapping intellisense
Example application: Cuyahoga CMS source
Example application: CodeCampServer

Published Saturday, January 26, 2008 3:03 PM by mhinze
Filed under:

Comments

No Comments