NHibernate 3.0 is the first major release of the popular ORM in over a year. With the release it has changed the CLR version to .NET 3.5. This allows the creation of the QueryOver API, while replaces the string-based ICriteria expressions with strongly typed lambda expressions. This is in addition to the built-in LINQ provider.
There are a number of breaking changes in this release. One change is improved support for nullable types. In previous versions “when using a <map> with an <element> that is a nullable type (DateTime? for example), you can't insert or update records with a null value.” Instead of silently ignoring the null value like past versions, NHibernate 3.0 will now correctly update the database. A couple of function signatures have changed and the methods marked as obsolete in previous versions have been removed.
In related news, Patrick Smacchia of NDepend is offering a code analysis report on NHibernate using said tool. Patrick’s opinion of what that analysis means can be found on the NHibernate blog. He summarizes it as:
For a brief summary, NH is ok on:
- The too many assemblies problem (my god, 95% of professional projects I can see have hundreds of asm, without any valid reason except to dramatically slow down everything on the developers workstation and build machines!!!)
- Not enough code coverage, NH has a healthy global 76% code coverage ratio. I mean, just NH handcrafted and generated code, not counting test code. Btw, around 18K LoC are generated on a total of 63K LoC.
- API breaking change, the team is pretty careful with the NH public surface and this attention is made obvious by comparing NH V3.0.0 with the previous NH v2.1.2 version.
- Dead code
I found room for improvement in:
- Code contract usage, NH doesn't use any code contracts Fx (nor MS Code Contract API nor Debug.Assert(...)).
- Despite the global great 76% code coverage ratio, many methods or types are 90%+ covered by tests instead of 100%. The problem is that often, subtle bugs hide in the remaining few percents hard to test and not covered code.
- A better global code architecture (this is not feasible since NH public API cannot be refactored for obvious reasons)
- A respect for basic code metrics quality thresholds (too complex methods, god classes, fat code, methods with too many parameters etc...).