So, I'm half way through the week and had a chance to reflect on all the information I absorbed at the UK Alt.net conference last weekend. There were 4 sessions I attended during the day and the 3rd session was titled “NHibernate, Linq and ORM”. Out of all the sessions I attended, this was probably the largest. The majority of attendees of this session were NHibernate advocates. For me, when it comes to NHibernate the jury is still out, the following article describes one of the reasons why.
Just to give you some background, I have been using NHibernate in-depth on a project for the last 9 months. I am no expert in the field but no novice either. Before using and ORM tool, I would write stored procedures in order to access crud functions of the database. Actually, “writing stored procedures” is overstretching, I would use codegen tools, run them over the database and plug my code into the resulting assembly. This was cool for a number of reasons, firstly the output assembly would show any changes or conflicts in code at compile time, and secondly it defined an explicit contract with my data store. I’m big on scaffolding in code (I know its not 100% TDD) but it provides a great way to visualise your overall code architecture.
When I started working on the project, I had very little exposure to ORM tools. I had read blog posts & articles but had never really cut my teeth on the technology. I would say that in the .net world, NHibernate is probably the no 1 ORM tool available. NHibernate is a port of the java implementation Hibernate which has been popular for many years.
The thinking behind ORM tools is that they “become the database” and that you really don’t need to waste time writing SQL anymore. I have to say, the moment I started reading about ORM tools I felt a little uneasy. SQL is a language I am very comfortable with, more to the point it has been specifically developed in order to query data in a mathematical and consistent way. The idea of not touching SQL and focusing purely in code seemed a little frightening to me. Trying to put my fears aside, I joined the project and jumped two feet into NHibernate.
Now during the last 9 months I can honestly say that the NHibernate learning curve can be a little erratic. Initially the model seems simple with a mapping file connecting your entities to the database. But as you continue, issues such as inheritance, polymorphism & lazy loading all start to impact your productivity. Now let me make it clear, all those issues can be solved with NHibernate in an elegant way, however finding that way takes time. One of the biggest problems I faced was an issue with entities that did not require to be saved. See the model below.

In this model we have all objects connected in a parent-child fashion. In this case the AssignmentCBI class which does not have a related database table, controls access into our complex system. This posed a bit of an issue for me as Nhibernate infers saving via a mapping file and in this case the AssignmentCBI class does not exist in the Assignment.hbm file. Therefore, I felt I had run into an Object/Relational Impedance mismatch. Again, it was just my understanding of NHibernate, I soon found that I could solve this problem using NHibernate Components. So as you can tell, NHibernate is a large beast and it issues such as these that can really throw a spanner in your productivity. But they are not issues that cannot be resolved.
NHibernate’s inherent Tight coupling
As my confidence with NHibernate has grown, I have felt that most issues can be resolved, all you need is the knowledge. However, there is one issue that I feel NHibernate creates that cannot be resolved. As I mentioned previously, I used to use stored procedures to interact with my database. Stored procedures in my mind are great as they enforce a contract between application code and the database.
Recently however, I hear people at conferences make snide remarks about them, like they are some form of pollution in the their code. I find this reaction strange, everywhere else in our code we spend time make sure there are adequate layers in order to reduce complexity and shield us from breaking changes. So why is it that I hear people turning their nose up at sprocs? The answer lies in the history of sprocs, I think many of us have experienced sprocs that may be 100’s or 1000’s of lines of code. These procedures are in essence business logic, it’s this bad habit that has forced us to abandon them. A decision I feel is incorrect.
What stored procedures really are are “service contracts”, regardless of bad practices implemented by devs or dba's in the past, they still serve a purpose in that they decouple the database schema from our application code. Its this important fact that I believe NHibernate misses and as a result leads to tight coupling between application code and the database schema. (Please note: I know NHibernate can use stored procs instead but I question the value NHibernate offers over codegen in the same situation).
Lets take a simple mapping file for an address entity (shown below)

In this mapping file, we can see that properties on our entity map directly to database columns. This is the most common pattern used by developers working with NHibernate. Now let’s jump forward.. say 6 months after our application has gone to production, I am a DBA and I need to restructure the Address table as new services are consuming that data or execution plans are bringing the server to a halt. I want to rename columns and move the notes field into a separate table specifically designed for notes data. I can do this via simple script, however what I do not realise (being the dba) is that I have an application that is tighly coupled to the address table. I have an issue where changing the database could break any number of applications that depend on the data. I just don’t know!! More importantly, the developers who wrote the application are no longer around (written by a supplier perhaps). I don’t even know about the dependency FULLSTOP as I cannot see these application server that may sit in disparate regions. What we have effectively done is create a long dependancy & support issue for our applications.
We could look to resolve this issue by implementing our mapping file so that it points to a view rather than the table, this however will only go so far, updates and deletes may need to span many tables which will be impossible to implement via view.
The answer is not clear, NHibernate & other ORM tools rely on mapping properties to database columns. This pattern results in tight coupling that makes applications suffer from a poor resistance to change. We as developers cannot assume that the database is just for the application we are developing, data is a commodity and therefore commonly shared amongst multiple services, and the querying of that data may be good for one scenario but not the other.
Its seems ORM’s fall right into this hole, they offer us productivty but at a cost. As I said, the jury is still out for me as to whether the pro's out weight the cons but being aware is vitally important.
I have a number of other issues I have comne across since using ORM's and I will be looking to blog about these in the future.