This is the second post on my series on ORMs.
ORM advocates will tell you something like the following:
- With an ORM we can concentrate on the business logic instead of the mechanics of storage and persistence of data.
- The underlying DBMS can change without our having to change the business logic or downstream code.
- Effort spent worrying about SQL is wasted effort. A programmer wants to work with objects so this friction is called "the impedance problem". Object mapping is the low impedance alternative.
- Using tool-generated SQL vs hand-crafted SQL can reduce SQL injection attacks
Let's explode these myths one by one.
1. With an ORM we can concentrate on the business logic instead of the mechanics of storage and persistence of data
In a way, this is true. I no longer have to hand-craft an INSERT or UPDATE statement against my base tables. The ORM removes the mechanics of doing this. But so does any good data API, including stored procedures. I've worked on many good applications where all INSERTs and UPDATEs were handled via "setter" stored procedures. For the most part the guts of each of these procs was very similar. So I'm not really sure how much time anyone really spent worrying about the mechanics of this once the basic data access "pattern" was defined. I'll argue that it would take as much time to get the data access pattern nailed down as it is to learn the ORM.
As for worrying about the persistence of data...I don't even know what that means. I let the DBMS engine handle that.
The real problem I see with ORM abstraction is that it is a completely application-centric approach to the abstraction. The abstraction is done on a "per application" basis, not "per database," so you're actually abstracting the database to one application, not to every application that accesses the database, as should be the goal, and which is the net effect of creating the abstraction layer in native SQL Server objects such as views and stored procedures.
2. We can change the Underlying DBMS Much More Easily with an ORM
I highly doubt that. If that were possible I should be able to profile any given call from my ORM to my SQL Server, strip out the "dynamic" stuff, and execute it against the same structure in Oracle. It will actually usually work because the ORM generates SQL to the lowest common denominator across all supported vendors. So when you have complex logic that does conditional JOINs (which each vendor handles differently), for instance, the ORM will fall back to bringing all of the data to the client and filtering there. In many cases the SQL is too complex for dynamic, ORM-generated SQL to handle which means we fall back to coding stored procedures anyway. Stored procedures are never portable between DBMSs, and likely won't ever be.
What the ORM advocates are really saying when they trot out the vendor-agnostic features of their product is that they are "separating the interface from the implementation" for you. The object-oriented design principle of separating your interface from your implementation, and then coding to the interface, is considered a Best Practice. So the vendor is saying "code to my ORM interface" and not your DBMS vendor implementation. And the OO people are sold on this. But aren't you really just coding to that ORM vendor's implementation of ORM? What I mean is...aren't we still stuck with vendor lock-in, this time the vendor being the ORM vendor and not the DBMS vendor? Or can we swap out Hibernate for Spring? I doubt that.
Let's assume you don't buy my argument. We still don't need an ORM to get interface/implementation separation. Your database developers and DBAs should be doing this for you. You really should never code directly against a table (the implementation) rather data access should go through the interface which is likely a stored procedure. Stored procedures have defined inputs and outputs which become the data contract that should be inviolable. You could still use an ORM but simply have it call the data API instead (stored procedures)...but the ORM vendors don't like that (I'll talk about why in a future post in this series...suffice it to say, if you use a stored proc then the vendor can't lock you in as easily).
Assume you need to change DBMS vendors. The data tier will need to change to handle the very different nature of different vendors' stored procedure implementations. And of course then each stored procedure would need to be changed to support that vendor's dialect of SQL (Transact SQL vs PL/SQL for instance). Granted, this isn't easy but if we want high performance it is necessary.
3. Effort spent worrying about SQL is wasted effort. A programmer wants to work with objects
Sorry, I don't buy it. You have to know your data if your product is going to succeed. I really don't care what a developer wants to work with. The customer really just wants accurate data for their reports. If that means that my developers have to worry about SQL and databases and not about Java or Rails or whatever, then so be it. Until the impedance mismatch between objects and data is truly solved, this argument is bunk. I don't think ORMs solve the impedance mismatch as much as the proponents think.
4. Using tool-generated SQL vs hand-crafted SQL can reduce SQL injection attacks
I don't doubt this argument. However, I believe a good knowledge of stored procedures and understanding of what SQL injection is...as well as defensive programming patterns, is even better.
In the next few posts I'll cover some of the things that I see as major problems with ORMs.
data architecture orm