I am a fan of ORM and have used NHibernate extensively on a large project over the last few years. Prior to that, I had used TopLink and Hibernate on java projects.
Ayende’s listing pretty much summarizes why I like NHibernate and also has points that apply to many other ORM products as well:
- Caching. NHibernate is specifically flexible in this area but many ORM products excel in this area over sql based DAL implementations.
- Multi-database support. Using an ORM insulates your code from the differences in database dialects. This might sound insignificant, but if you have ever had to migrate any application from Oracle to SQLServer, for instance, you will know what a chore it can be.
- A dramatic reduction in plumbing code for your application. Although he does not directly say this in his list, he does mention writing applications with no sql in them. What I’ve noticed is that there is a ton of code that gets written in your application just to put data in your domain model and pull it back out. Using an ORM removes this code from your application and puts in the domain of the ORM, which is code someone else writes and tests.
Using an ORM seems to encounter a great deal of resistance from some enterprise developers. Below are a few of the reasons that are usually given against using an ORM product on a project:
- Even though you are not writing sql, you still have to perform the mapping.
- The sql generated by the ORM cannot be optimized for specific cases and will be slower.
- Using reflection is slow.
- Using an ORM makes the data access problems more difficult to debug.
- Everyone knows sql and nobody knows <ORM product>.
Even though are not writing sql, you still have to perform the mapping
This is a good point. It is true that the work of mapping data to columns in a database is moved from sql to the mapping layer of the ORM. In the case of NHibernate, this would be XML files. So in that instance, no work or time is saved. Where the time savings comes in to the picture is when the actual mappings are used. NHibernate takes those mapping files and performs the domain object instantiation and population for you.
Detractors of the ORM approach might counter with the argument that the usage of the ADO.net data constructs, for instance the typed dataset, also removes the need to write object population code. Although this might be true, I believe that passing ADO.net data types around your application leads to poor application architecture, not to mention performance problems. Typed datasets are notoriously slow when it comes to serialization.
The sql generated by the ORM cannot be optimized for specific cases and will be slower
This might be true for certain ORM products, but has not been my experience with NHibernate. The generated sql is quite good. However, I have encountered situations where the sql has been unacceptably slow and in those cases I can almost always place the blame on a poorly designed database model.
NHibernate has the ability to pass sql to the database, if needed. SQL optimizations can also be placed in the mapping files to help in situations where NHibernate could not generate the optimal queries. Named Query support, added to NHibernate 1.2, has helped as well for specific query situations that might not be the normal path for searching for a given object type.
Using reflection is slow
This is always an interesting discussion to have with a stubborn developer. Yes, it is true that a method invocation via reflection would be slower than a method invocation compiled into the IL directly. The tradeoff you are making is flexibility for a little speed. The reality of the situation is that the slowdown for reflection will be dwarfed by the IO wait for the database and you will not notice it.
NHibernate also has functionality called the reflection optimizer which will dynamically generate classes for populating your domain objects at startup time. This a tradeoff in startup time to remove the cost of reflection for each domain object population. Early versions of the reflection optimizer were noticeably slower at startup for larger numbers of mapped classes, but this has been corrected in the newer versions of NHibernate.
Performance problems in enterprise applications are caused by poor database design or poor approaches to data retrieval in 99% of cases. I should also lump screens that have too much data on them in with this category as well. The other 1% of the time the performance problems are caused by poorly written threaded code, poor algorithms, and poor integration choices with 3rd party applications. I have never encountered an enterprise application that was too slow because of reflection usage.
Using an ORM makes the data access problems more difficult to debug
I hear this complaint a lot at the beginning of projects specifically from developers that have never used ORM before. I would say that the real statement that should be made about the subject is:
Using an ORM makes the data access problems different to debug.
Most of time, a developer simply needs to familiarize themselves with the debugging facilities available in the ORM tool they are using. There is cost to learning what is available, just as there is a cost up front for learning any new tool or concept, but the productivity that ORM gives a project overall will make up for the learning curve.
Everyone knows sql and nobody knows <ORM product>
I also hear this complaint a lot at the beginning of project where I propose using ORM. It is difficult to convince someone that ORM will payoff after the learning curve is overcome when they have never used an ORM product. There are many blog posts on the web complaining that ORM does not pay off in the long run but this simply has not been my experience.
The response I usually give is to try the product for a pilot or proof of concept to test the pluses and minuses. Most clients are won over when they see the benefits of caching in the ORM and the ability to migrate databases with just minor mapping file changes (or maybe none). Also, when they actually try using NHibernate or another ORM product, they find that the product is not quite as unapproachable from a technical standpoint as they thought when they first heard of the concept.