Apr 26, 2014
There is a lot of ORM hate lately. Some people even call it The Vietnam of Computer Science.
First, let’s clarify the difference between ORM and ORM tools.
ORM — object-relational mapping — is a technique used to map object-oriented constructs like classes and objects to relational database structures like tables and rows.
An ORM tool is a particular tool like Hibernate or Doctrine that does that mapping for you.
If the model in your application is implemented in object-oriented style and you use a relational database to persist data, ORM is not a choice. Whether you like it or not, you have to map the application code to the relational constructs of the database.
The only choice you have in this case is whether to use an existing ORM tool or roll up your own. That’s it.
Of course, there are other options like using NoSQL tools for persistence or abandoning OO style in the model, but that’s another story.
While ORM itself is not a choice, there is a choice in using an ORM tool in a way that makes it suck less.
I see this too often. A lot of developers generate their database schemas with an ORM tool and that’s a bad idea.
First, ORM tools suck in schema generation. They generate schemas in probably the most blunt way one could imagine. They also name constraints with useless names like
IDX_9C0600CAF6BD1646. If you don’t name a constraint explicitly, sane DBMSes like PostgreSQL will come up with much better names on their own.
Second, ORM tools try to support as many DB vendors as possible, so they use only a portable subset of DDL. This means they can’t take advantage of powerful features of a particular DBMS you went with. For example, PostgreSQL has a
CHECK constraint that an ORM won’t generate:
1 CREATE TABLE person 2 ( 3 sex varchar NOT NULL, 4 CHECK (sex IN ('male', 'female')) 5 );
Take back the control of your database schema. Write database migrations in plain SQL and adapt ORM mapping to it — not the other way around.
Design your schema using relation databases idioms and then use an ORM tool to map the schema to the application code. Do not bend your schema to please a particular ORM tool you’re using.
For example, there are ORM tools that force you to have an autoincrement ID field playing the role of they primary key in each table. From the relational database design point of view, it doesn’t always make sense to add a surrogate key when you already have a natural one. For example, ISBN is a great natural key for a book; you don’t have to add a surrogate ID column to the books table.
If your ORM tool forces to bend your schema to its own will, look for a better tool.
Some ORM tools force you to extend some base class or do something else to please them. Those are mostly implementations of the Active Record pattern.
There are other ORM tools that implement the Data Mapper pattern and they let you keep your model structure the way you would if you were not using an ORM tool at all. Hibernate and Doctrine are examples of that.
Do not let an ORM bend your model to its own will. If it does, throw it away and find a better alternative.
Since marshalling objects to rows and back is mostly boilerplate code and very boring to write, it’s a good idea to use an existing ORM tool to do that for you. Just don’t let it do anything else because that’s out of ORM and ORM tools concern.
ORM is not a choice when you have OO code on one side and RDBMS on another. But there is a choice of ORM tools and ways to use them that suck less.