One of the topics of seemingly perennial discussion among programmers is whether object-relational mapping (or ORM) is evil or not. Opinions seem to run the gamut from “I use and love it” to “I tried it once and never will again” and often encountering at least a few “what are you talking about?”s.
So for any “what are you talking about?”s, a little explanation. In an object-oriented system there’s a high probability that you’ll eventually need to safely store your objects so they’ll survive a power outage, memory exhaustion, process shutdown, etc. You’ll probably end up storing these objects in a relational database of some kind, and you’ll probably need a system by which your system objects become valid database records. Ideally, that same system should give you back your objects from that same database next time you need them and they aren’t in memory. That’s essentially what people use object-relational mappers to do.
Among ORMs, there are a two very common philosophies or patterns: Active Record and Data Mapper. These two have advantages and disadvantages, let’s explore them.
Active Record: The Web’s Favorite ORM?
If most programmers know about active record, it’s because they’ve used it in web framework. Ruby on Rails is built around Active Record, as are most PHP frameworks like Laravel, Yii, CodeIgniter, and CakePHP.
The essential concept of the active record pattern is that your database records are “active” in your system. Practically what that means is that if you’re touching five BlogPost
objects, and you save them into your database, there’s a high probability that they’ll end up as five rows in your blog_posts
database table. What’s more, if your BlogPost
object has postContent
and publishedDate
properties, that allows us to assume that those are columns in the aforementioned blog_posts
table.
The Good: Why People Like Active Record
- Simple. Because of how tightly matched the records in your database and the objects in your system are conceptually, it’s really easy to pick up a project, examine its database schema, and have a strong sense of what the project is doing. What makes this great is that the ORM layers have a minimal amount of indirection. What you see in the database or objects is likely what exists in the other.
- Easy to learn and understand. This flows directly out of the simplicity, but you’ll also probably have a pretty intuitive understanding of how you can work with this system even if you’ve never had the least exposure to an ORM before. Its simplicity is merciful and easy.
The Bad: Why People Be Hating
- Database coupling (and testing). Because your database is so tightly coupled with your objects, you’ll have a hard time efficiently separating the two. Surely a good active record implementation is likely to make it pretty quick for you to switch from MySQL to Postgres, but it’ll not make it easy to use your objects without the database. The fact that most active record model-based systems are effectively impossible to separate (for testing or other reasons) is often held against them.
- Performance bottlenecks. A very similar complaint about the active record pattern is that you’ll have a hard time dealing with performance bottlenecks when they arise. For small web-apps with a few hundred users this generally isn’t an issue, but the lack of SQL efficiencies that more complex systems of separation between your system objects and your database allow are a big road block as Active Record-based applications grow.
The More Enterprise-y Data Mapper
The biggest difference between the data mapper pattern and the active record pattern is that the data mapper is meant to be a layer between the actual business domain of your application and the database that persists its data. Where active record seeks to invisibly bridge the gaps between the two as seamlessly as possible, the role of the data mapper is to allow you to consider the two more independently. Java’s Hibernate and PHP’s Doctrine2 are the two prototypical data mapper facilitators in my mind, though I have little doubt that there are many others.
The Good: What Data Mappers Allow
- Allows for greater flexibility between domain and database. As we mentioned above, one of the prototypical reasons that you’ll want to use a data mapper is that you as the application architect do not actually have final say on the database scheme. Where you’ve got a historical database, or a new database with an unfriendly gatekeeper, the data mapper pattern allows you to hide the ways in which you database isn’t an ideal way to think about your domain behind the whole data-mapping layer.
- Can be much more performant. Similarly, because you do have a layer of abstraction and indirection between your domain objects and your database, there’s a good possibility that you can have the data mapper make more efficient use of the database than a naive active record implementation would allow.
The Bad: Data Mappers Are Hard
- Often intimidating and hard to set-up. The advantage of active record is that you build your database schema and objects side-by-side, so when you’ve got one you’ve got the other. Because the data mapper pattern is deeper than that, you’re inherently going to have to think a little harder to configure your data mapping layer than you will a practically-invisible active record layer.
Final Notes on Object-Relational Mapping
I recently (finally) got around to watch a conversation Martin Fowler — who basically is the reason these patterns are known by these names — had with his colleague Badri Janakiraman about Active Record and its role in a “Hexagonal Rails” architecture. You might want to check it out. On that same topic, I also enjoyed an informal conversation organized by Shawn McCool and a number of other PHP developers on the topic.
In general, the question of which ORM system to use (if any) is not one with a clear set of answers. Maybe it makes sense for you to have your database as a part of how you think about your application domain: if it does, there’s not really a good reason to go all the way to a data mapper. That is specifically the case Martin and Badri talk about in their conversation, and both seem to be very satisfied with the result.
The only thing I know for sure: a dogmatic answer to the question of what ORM to use is probably not going to the best one for all possible circumstances. What matters most is that you choose how you work with the database based on what makes the most sense in your specific case, not which general answer is most popular today.
The post ORM Patterns: The Trade-Offs of Active Record and Data Mappers appeared first on Press Up.