Yesterday I read a blog post by Kenneth Downs entitled “Why I Do Not Use ORM” on his The Database Programmer blog. It wasn’t the first blog post with gripes about Object Relational Mapping, and it certainly won’t be the last. For me, this particular article highlighted a few misconceptions about why and how ORM should be used, and I thought I might chime in with my own perspective.
ORM is not a way to avoid
SQL
The first thing that stood out for me was this quote:
> “The language SQL is the most widely supported, implemented, and
used way to connect to databases. But since most of us have long lists
of complaints about the language, we end up writing abstraction layers
that make it easier for us to avoid coding SQL directly.”
To his credit, the author wasn’t actually addressing ORM in this paragraph. However, anyone writing business logic which interacts with a database, who is unable to write some basic SQL, is like a bull in a china shop; nothing good will come of it regardless of the tools and abstraction layers employed.
The Simple Example
The next example in the post shows how one would write a row to a
database in only four lines of PHP code – it looks something like this
(I removed the comments):
$row = getPostStartingWith("inp_");
$table_id = myGetPostVarFunction('table_id');
if (!SQLX_Insert($table_id,$row)) {
;
myFrameworkErrorReporting() }
I don’t know PHP, but I think the code is reading every field in a posted form that starts with inp_, generates an insert statement straight from the ID’s on the form fields, and writes an insert statement with the results.
Perhaps it’s unfair to criticize this code because “it’s just a simple example,” but if this code is being held up as an example of how short and simple non-ORM code can be, one does have to wonder * When the database schema changes, does the HTML need to be updated so that the form fields match the database schema? * Where are the transactions? What if I need to insert into several tables and roll back the transaction if one fails? * Does the handy SQLX_insert method prevent SQL injection attacks?
He goes on to say that this task is made even easier by using a data dictionary to generate the SQL. After reading the “Using a Data Dictionary” article, one has to wonder whether or not the author realizes that it is a very crude form of ORM.
What about Business
Logic?
Kenneth Downs tries to head-off any arguments about business logic
before they come up, knowing that ORM evangelists will argue that the
domain objects can encapsulate essential business logic for the
application. His response?
> “The SQLX_Insert() routine can call out to functions (fast) or
objects (much slower) that massage data before and after the insert
operation. I will be demonstrating some of these techniques in future
essays, but of course the best permforming and safest method is to use
triggers.”
For me, this sounds alarm bells. Triggers slow down transactions. Triggers are in your database, which is often your system’s biggest bottleneck. Triggers silently do things behind your back without telling you. Triggers change databases from vast, efficient places to store relational data, into a lumbering behemoth interpreting procedural code inside big iron.
Conversely, business logic that can be easily distributed across many smaller web servers scales horizontally. The domain layer is a fantastic place to embed simple data massaging – sadly, I often see a pile of persistent entities with getters and setters that don’t do anything.
Counter Example: The Disaster
Scenario
Lastly, Ken (can I call him that? What is the ettiquite for this sort of
thing, anyway?) shows an example of a piece of code that is likely to
cause hundreds of unneeded reads to the database in an untuned ORM-based
system. I don’t dispute this; in fact, I posted
about an almost identical nightmare scenario myself a while ago.
For this, I go back to my “bull in a china shop” analogy. Programmers can write horrible code in any language, with any tool. Layers of abstraction are a double-edged sword, because you need to understand what they are doing for you. But it’s not the tool’s fault; it’s the person misusing it.
Computer Science’s
Vietnam
In 2004, Ted Neward famously called ORM Computer
Science’s Vietnam. Encouraged by early successes, we got sucked into
the quagmire. There are plenty of reasons to be frustrated with ORM, but
I’m not sure I agree with Ken’s. I try to hit the 80/20 rule with ORM,
and use it where it makes sense. When I get into a convoluted
transaction or need to do a large batch of operations, I’m not afraid to
dive into SQL and do the work in a stored procedure. I think it’s a good
mix. How about you?