New thoughts on writing database applications
published: Wed, 18-May-2005 | updated: Thu, 27-Oct-2005
Over the past few weeks, we, the Architecture team at Configuresoft, have been involved in designing the Next Generation architecture for our product. My area of responsibility is the "middle tier", which ranges from the layer that accesses the data from the database engine, all the way up to the presentation layer, the bit just under the UI. Yeah, lotta work.
Now, in previous lives, I've designed and written multitier applications. The last one I did wasn't too shabby, even though I say so myself: I wrote code to generate the database schema and used CodeSmith to generate most of the code for the CRUD stored procedures and the business objects. The framework I was using was Rockford Lhokta's CSLA (Component-based, Scalable, Logical Architecture), and I was using the C# version (starting with his beta version).
Nevertheless there were some issues that, because of the particular contract I was on, I couldn't solve. The code that accessed the data from the database was inherently targeted to SQL Server. That wasn't a problem in this particular job (it's the database that the customer used), but in this Configuresoft project we want to configure the system for different database engines.
Another issue was that I eventually reached the point where I had to put away CodeSmith and modify the generated code directly. Again, because of the short time-scales on this project, I had no time to refactor for a better solution. And, I hasten to add, this is not necessarily a problem with CodeSmith or CSLA per se, it's an endemic problem when you have generated codebases.
Then, because I was using a code-gen design, it meant that my mapping from table to class was simple and one-to-one. My object model was simple in the extreme and consequently very hard to use (for example, records in link tables became link objects in a list). Yuk. The one and only time I attempted any kind of inheritance, it was just plain awkward and the cause of many orphaned record bugs.
In other words I ran into the classic object/relational mismatch issues. And this got me thinking as I contemplated the middle tier: why not use a proper object/relational mapping (ORM) framework?
So, over the past two days, I've been feverishly reading Hibernate In Action by Christian Bauer and Gavin King, trying to get a handle on ORM tools, especially Hibernate (or more likely NHibernate). Holy friggin' cow. It's bloody beautiful. Man, I'm sold.
Hibernate is an ORM library for Java. It enables you to design a Domain class model as POJOs (Plain Old Java Objects), write some mapping metadata (which class maps to which table, which property maps to which column, how an association works, the inheritance tree), and Hibernate does the rest: automatically generating dynamic SQL (according to the database engine you're using) to persist the dirty object graph (not just a single object, mind, but the whole bloody graph) to the database.
Now, I'm not saying that it's only Hibernate that does this, all ORM tools do this to a greater or lesser extent, it's just wonderful how this technology has grown so much so fast over the last couple of years to attack the OODMSs of the planet.
I'll certainly be talking more on this subject. Stay tuned.