Creating an Object-Relational Mapping (ORM) has become the de facto way of handling persistence in the object-oriented programming paradigm. Almost all systems require some form of persistent state, and relational databases have become the de facto place to put that state. Relational databases are proven, scale well, and organize data in a tabular manner suitable for many of the real world problems that we try to solve, so they are an obvious choice. Choosing them, however, means we have a new problem at our hands, known as the object-relational impedance mismatch.
The problem is that a relational database is not suited for storing an object-oriented model. An object is almost always a non-scalar value, meaning that it won't fit well in a table row. Hence, we have to create a schema suitable for persisting our objects to a set of tables. This schema will be different for each type of object we have, so it's a rather tedious task, but it solves the problem.
As always, we developers tend to dislike repetitive tasks, so we try to simplify and automate the extra work involved with creating an ORM. This has led to various design patterns such as DAO, and in recent years a set of fully automated ORM tools such as Hibernate (Java), NHibernate (.NET), SQLAlchemy (Python), and Propel (PHP) have become very popular. These tools offer a highly transparent solution to the ORM problem, at the addition of a cost that varies heavily with the nature of the ORM problem. Still, their presence moves us closer and closer to a solution - we are creating an abstraction that fully encapsulates the difference between a relational database as our storage for persistent objects, and the objects themselves. Hopefully, we will soon be able to create an ORM that induces a linear or perhaps even constant cost on our solution, regardless of the nature of the problem we are trying to solve.
But wait. The real problem we are trying to solve is how to persist the state of our objects, remember? The database is indeed a store, and hence a candidate solution, but using it introduces an impedance mismatch, which is another problem we need to solve. It really is like trying to fit a square block in a round hole.
Let's stop trying to solve the wrong problem of creating an ORM, and start finding a solution to our initial and real problem of persisting our objects. Recent innovations such as LINQ have taken us a step in the right direction by making persistence an integral part of the language, but we're still a long way from automated persistence for our objects. I am certain, though, that moving focus away from the challenges of an ORM and on to the challenge of persistence in general will take us further.
Let's do that.
(And I'm sorry for reusing Dijkstra's already overused] phrase, but I couldn't resist.)