This weekend, Tim Bray posted a link to an article at Seldo.com that argues that ORM is an anti-pattern. If you don’t know what ORM is, you probably won’t find this post very interesting, but I’ll provide a brief definition. ORM (object-relational mapping) is a layer of abstraction that stands between your database and code and allows you to treat entities in the database as native objects in whatever language you’re using. The advantage and disadvantage is that it substitutes native calls for SQL.
The linked article does a good job of going over the downsides of using ORM, but I think it ignores the upsides. His most compelling argument is that you should be using SQL appropriately in your application rather than trying to avoid it using ORM instead:
But in my experience, the best way to represent relational data in object-oriented code is still through a model layer: encapsulation of your data representation into a single area of your code is fundamentally a good idea. However, remember that the job of your model layer is not to represent objects but to answer questions. Provide an API that answers the questions your application has, as simply and efficiently as possible. Sometimes these answers will be painfully specific, in a way that seems “wrong” to even a seasoned OO developer, but with experience you will get better at finding points of commonality that allow you to refactor multiple query methods into one.
I think that he undersells the utility of ORM when it comes to simple queries and inserting and updating data. I work on a Web service that processes transactions. Each transaction involves a user logging in and the retrieval of a number of settings from different tables. When I’m done processing a transaction, I have to insert dozens of rows of data into at least half a dozen tables. All of the data that is retrieved and stored is already represented in the object model of my application. Hibernate, the ORM library we use, is remarkably good at pulling up the data when users log in using simple queries, and more importantly, saving all of that data using inserts and in some cases, updates.
Using ORM in the transaction processing context has saved me a massive amount of time over the years, and helped avoid stupid countless bugs involved with manually updating the SQL statements in the data access layer every time I update the object model. Coding that SQL by hand would offer nothing in the way of performance nor would it make the application any more understandable.
The main downside is that on the few occasions when I do have to write Hibernate code to ask questions of the database, I pretty much have to look up the proper approach every time. It would be much easier in SQL since I already know SQL very well.
The secret is, I think, to use the right tool for the job. The main manner in which we avoid the downsides of ORM is in not using it at all for the reporting part of our application. For reports, we use a data access layer that just uses SQL to access the database in a purely relational fashion. Just as writing SQL for all of the basic create/read/update/delete operations in our application would be painful, trying to write well-optimized reporting queries through the ORM layer would be as well.
Categorically rejecting a class of tools that are used productively on thousands of projects is just as silly as picking the wrong tool for the job. Either way, you give yourself more work than is necessary.