BT

Debate: Comparing NHibernate and EF 4

by Abel Avram on Jan 12, 2010 |

Recently, a post by Oren Eini (a.k.a. Ayende Rahien) touched off a debate around the respective merits and capabilities of NHibernate and Entity Framework 4.0, two .NET-based Object/Relational Maping frameworks. InfoQ explored this debate in more detail to understand some of the perspectives which were given.

Rahien, a member of the NHibernate project, made a quick comparison between NHibernate and Entity Framework 4 (EF). After appreciating the progress EF 4 has made in regards to EF 1.0, Rahien enlisted several features that, in his opinion, make NHibernate a better ORM solution:

  • Write batching – NHibernate can be configured to batch all writes to the database so that when you need to write several statements to the database, NHibernate will only make a single round trip, instead of going to the database per each statement.
  • Read batching / multi queries / futures – NHibernate allows to batch several queries into a single round trip to the database, instead of separate roundtrip per each query.
  • Batched collection loads – When you lazy load a collection, NHibernate can find other collections of the same type that weren’t loaded, and load all of them in a single trip to the database. This is a great way to avoid having to deal with SELECT N+1.
  • Collection with lazy="extra" – Lazy extra means that NHibernate adapts to the operations that you might run on top of your collections. That means that blog.Posts.Count will not force a load of the entire collection, but rather would create a "select count(*) from Posts where BlogId = 1" statement, and that blog.Posts.Contains() will likewise result in a single query rather than paying the price of loading the entire collection to memory.
  • Collection filters and paged collections  - this allows you to define additional filters (including paging!) on top of your entities collections, which means that you can easily page through the blog.Posts collection, and not have to load the entire thing into memory.
  • 2nd level cache – managing the cache is complex, I touched on why this is important before, so I'll skip if for now.
  • Tweaking – this is something that is critical whenever you need something that is just a bit beyond what the framework provides. With NHibernate, in nearly all the cases, you have an extension point, with EF, you are completely and utterly blocked.
  • Integration & Extensibility – NHibernate has a lot of extension projects, such as NHibernate Search, NHibernate Validator, NHibernate Shards, etc. Such projects not only do not exists for EF, but they cannot be written, for the most part, because EF has no extension points to speak of.

As advantages of using EF 4, Rahien mentioned:

  • EF 4.0 has a better Linq provider than the current NHibernate implementation. This is something being actively worked on and the NH 3.0 will fix this gap.
  • EF is from Microsoft.

Being a known contributor of the NHibernate project, Rahien's post triggered a considerable number of pro/cons reactions. A reader, tobi, complained on NHibernate’s poor error messages:

As someone who has worked with NHibernate for only a few hours it seemed to me that the experience of manually creating domain classes and mappings (with FluentNHibernate in my case) was quite manual and the error messages were not that good. This is something that I would write onto the EF4 side of the comparison.

Roy had mixed feelings about error messages and documentation:

An additional pro for EF is that the documentation is more organized and error messages are more descriptive.
I still prefer NH though, but it takes a lot of blog-browsing if you have a problem. Conversely, the benefit of that might be that there are a lot of people you can ask questions to.

Jimmy Bogard appreciated how NHibernate’s bug fixing process makes it more alluring:

Another major advantage of NH is that it's OSS. I've needed to patch NH several times over the years, to fix a bug or add something I needed. With EF, I'm just stuck.

Alex Yakunin, involved in creating the ORMBattle.NET test suite, another ORM tool, complained:

I think you should explicitly state that only benefits of NHibernate are shown here. Disadvantages are almost untouched at all - even your words about LINQ provider are pretty far from truth; another well-known case is that EF supports change tracking, but NH does not, and this can dramatically affect on performance in set of cases (in fact, you should forget about certain cases in NH at all - just "by design").

Radenko Zec compared unit testing and designer capabilities:

I think that biggest advantage of NHibernate is better support for unit testing. EF4 is not designed for testing and it is very difficult to write unit tests for some custom solution based on EF4.
On another hand EF4 has very good designer (most important thing that you need for real world large project) and POCO T4 template based on that designer... I think that is time that you start thinking about making your own designer for NHibernate instead of denying need for designer and code generator. If community wants designer for NHibernate, give them good designer... And third party designers are miles away from EF4 designer except probably LLBGEN 3 that is not yet released and is not free.

Frans Bouma, the man behind LLBLGenPro, yet another ORM tool, mentioned NHibernate lacking badly when it comes to documentation:

What EF has over NH is documentation, solid examples and a large stream of evangelists speaking at every developer conference there is and pumping out articles around the clock. … NH sucks in that department (and please, don't come with excuses, it does suck in the documentation department. If you want to know how big it sucks in that department, take a tour in the DDL SQL producing docs for _N_hibernate and learn how great it can generate ... java classes. huh?), and at the same time has many options, it's not really an advantage to have.

Felix proposed a combined solution:

Don't remember who said ... "OR/M is the Vietnam of the Coding"... NH is a veteran, EF is young recruit. Unfortunately MS can't leverage OS, if they do life would be easier: designer and integrated tooling by MS, OR/M by NH would be a productive solution.

The general consensus appeared to be that NHibernate has a number of features which are missing from Entity Framework 4.0 like read/write batching, "extra" laziness, collection filters, tweaking, and others, however Entity Framework has a better LINQ provider, documentation and it is supported by Microsoft. What are your thoughts on this debate?

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

NH Designer by George Mauer

It was also pointed out several times in the comments thread that NHibernate has several designers. I've never used any but some of them I hear are quite good

NHibernate Hands Down by Scott White

If I don't trust a designer to spit out something as simple as HTML why would I trust it with something more important: my domain mappings. Frankly understanding ORM is not helped by a designer. Microsoft had a designer for strongly type datasets and they still sucked.

NHibernate is fundamentally better product from the ground up. One more often neglected pro for NHibernate is the interoperability between different RDBMS support for MySQL, SqlLite, PosgreSql and many more exist and can easily be written for NHibernate. EF is very lacking in this area.

Advantage Entity Framework by Ivo Limmen

I personally don't think it is a big advantage that the Entity Framework comes from Microsoft. I find products from Microsoft tend to be usable when it is more matured; say from version 2 and up. The Entity Framework in .NET 3.5 is clearly public beta quality.

It is a nice attempt and I am sure the next version will be lots better. I hope the same for LINQ.

Some other nHibernate problems by Martin Cronjé

I have been using nHibernate for a while and would still use it on some projects once EF4 is released.

The one major NH drawback is that it does not support controlled partial loads of object graphs (something that EF4 supports). NH lazy-loading feature is a good alternative but only works for 2-tier applications (App+DB), whereas the EF4 solution works extremely well in n-tier or scenarios. (Note: This depends on your design approach as some may not expose their DTO's as entities on their services)

Also worth mentioning is that the Iesi.Collections causes issues with serialisation when dealing with WCF (lunaverse.wordpress.com/2007/05/09/remoting-usi...) and lacks an indexer on ISet.

It's all about testing ! by Jérôme Avoustin

Development, architecture, etc. is all about testing !
What makes an application maintanable, flexible, etc ? Tests !
So EF as a big lack that makes it almost unusable !

And even if EF is supported by Microsoft, Hibernate is tested every day by .Net developers and the half of the Java community !

Loading custom or large object graphs in EF by Sam Meacham

I tried to point out on Ayende's post that EF is capable of loading large, complex object graphs not only in a single trip to the database, but in a single query (the generated SQL uses an efficient combination of subselects, joins, etc). You can use ObjectQuery<T>.Include(string associationPath) like this:

var q = from ent in context.Entity.Include("Child.GrandChildren").Include("OtherProperty.Children").Include("SomeOtherProperty.RelatedEntity")
select ent;

To get an entity (or entities), plus all of the related entities specified in the calls to Include(). The SQL generated will only be a single query, and the number of rows generated from that query will be N, or the number of unique objects in your object graph.

NHibernate cannot do this. IF you set your mappings up with <set> (<bag> will not work), then you can *sort of* accomplish the same thing using ICriteria<T>.SetFetchMode(string associationPath, FetchMode.Eager), but it won't be pretty for complex graphs that include multiple related entities, and multiple collection levels. The difference is that NHibernate will do flat joins for all of the tables involved, creating an enormous cartesian product of all the records. Then it will drag all those records over the wire (sometimes millions, depending on the object graph, which doesn't have to be large, 100 x 100 x 100 = 1 million), and waste a bunch more time sorting through the results to create the proper object graph. And if you map to <bag> instead of <set>, it won't even sort it out for you, and you'll just have a graph with millions of objects that aren't even related.

It was suggested to me that I use Future<T> or FetchMode.Subselect to accomplish this, but neither of those will provide me with the specific capability of loading complete custom object graphs in a single trip. With Future<T>, I won't have a graph. I'll have separate lists of related entities, so I end up not using my OO model. With FetchMode.Subselect (which can't be specified for a query arbitrarily, but must be specified in the mapping, locking me in to a default strategy), things are not issued in a single query, and I still can't get it to produce the correct object graph.

I have a blog post describing some of this problem in more detail, with more research being done, so more posts on the way. The reason I'm hammering on this nail so much is that I prefer NHibernate, and I think it is a superior product, and I would like to see better generated SQL that allows for more custom loading. The truth is that it's an uncommon scenario to have to load an object graph with so many related entities and collections eagerly fetched. If you're only going over 3 levels (root > collection > child collection), then the cartesian product probably won't be too bad, and performance is hopefully acceptable.

I'll be keeping a close eye on EF4, but for now, I still prefer NH.

Agree with Frans by JOHN W

I think that NHibernate is the preferred choice for those who are experts at using it, but for those with limited experience with ORMs, EF is a better choice.

While NHibernate has a solid following, it has some glaring weak points:
1) The lack of a solid IDE.
2) Poor documentation. I know that it's the nature of OSS, but it's a giant problem. To go from an immature tech shop to a continuous integration shop, you may need to learn about many different technologies, such as Git, CruiseControl.net, nUnit, Moq, Fitnesse, etc. It's a daunting task to learn everything without having to take even more time to search for where to learn.
3) Over dependence on a small set of developers. NHibernate does not have the community support that Hibernate does. If Ayende got hit by a bus tomorrow, NHibernate would struggle to survive. Also, look at the late adoption of LINQ support. We're on a new .Net version and NHibernate hasn't yet added that feature to an official release.

Re: Agree with Frans by Sam Meacham

"Over dependence on a small set of developers" is an incredibly valid point. I raised a similar issue not too long ago on the NHibernate google group, pointing out that certain OSS projects are so successful because they have commercial backings. The mozilla foundation has paid emmployees. Canonical backs Ubuntu, and Ubuntu developers are paid. Subversion has Tigris, etc, etc. OSS projects with monetary support get bugs fixed faster, develop mew features faster, and have better documentation. NHibernate developers should seek out a commercial parent company to sponsor them. I vie for NH at work, where other developers have pushed EF, because NH doesn't have a commercial foundation, or a large developer base.

EF is less mature yet I still use it because I know it will win by Tom Cabanski

Unfortunately, MS decided not to adopt NHibernate. EF is many miles behind for lots of scenarios but it will win anyway. That's why I have stopped using NHibernate despite the fact that I think it is still better. That is not to say MS will not catch up. EF4 has come quite a distance and I'm sure EF5 will be even better. I still really wish MS had adopted NHibernate and put effort into making it even better instead of starting from scratch.

Re: NH Designer by Fabio Maulo

NH has, at least, a Visual-Designer www.slyce.com/
Btw, when VS2010 will be released, and perhaps even before, you will see that NHibernate has the same Visual-Designer that has EF.

Re: Agree with Frans by Carlos Peix

@JOHN W

3) Over dependence on a small set of developers. NHibernate does not have the community support that Hibernate does. If Ayende got hit by a bus tomorrow, NHibernate would struggle to survive. Also, look at the late adoption of LINQ support. We're on a new .Net version and NHibernate hasn't yet added that feature to an official release.


Not stating that NHibernate has 100 developers but stating that there's only one denotes a missinformation. Fabio Maulo has contributed and is contributing as many as Ayende if not more. Specially lately. There're a lot of other contributors, as well.

Carlos Peix

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

11 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT