DEV Community

Discussion on: Subtle issues with ORMs, and how to avoid them

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

I use a "micro-ORM" (Dapper on the .NET platform). Literally the only thing it does for me is map objects to query parameters and query results to objects. It is an incredible help.

I have previously used full ORMs (NHibernate and Entity Framework), and I am not likely to go that route again. Hopefully I can explain my perspective in a cogent way. If I had to boil it down to 2 main reasons that ORMs have not fit for me, they would be: failure of one-true-model and impedance mismatch.

As I work on a system, I find that trying to use one-true-model for an entity (i.e. a single model represented by a set of database tables) does not work. The objects I use in code start no longer to map property-for-property to its storage structure (database tables). Simple example: Full-text search column... business logic could care less about it but UI needs it for queries. Resolving these differences in one-true-model becomes a source of ongoing complexity. At some point I need to mitigate that complexity. The usual way is to split the data model up into separate models organized around their specific concerns. I have to manually decide what data goes into what storage container (and in what shape). I could keep a separate set of storage objects, manually map from business object to storage objects, and then have the ORM auto map from storage object to SQL. But at this point it is more straight-forward to manually map from business object to query parameters without introducing and learning a new framework. The really tedious stuff can be avoided with a helper library with low conceptual overhead (like Dapper mentioned above).

Another case where an ORM seems handy is when you have some operational data that you usually load and save as a whole. Examples: limits, minimums, schedules around a particular entity. In this case the relational model introduces accidental complexity by making you split up sub-entities across multiple tables with parent-child relationships even though they are a conceptual whole. (Also called impedance mismatch.) Instead of using an ORM here, I find that using a document or key-value model often fits better. For instance in Postgres, I would store the whole object in one jsonb field. This is usually not so good for reporting (although Postgres specifically does offer indexing and searching on jsonb data). But I often find this is a lesser concern for the type of data where this pattern fits.

I am sure there exists a use case where a full ORM is a good fit. But most of my development (business systems) does not hit one of those cases. It is not so much that ORMs are bad. Its just that as my development habits have changed, they do not effectively solve a problem I have.

Collapse
 
joncalhoun profile image
Jon Calhoun • Edited

It definitely sounds like you are making the right decision for your particular use case, and I mostly prefer ORMs that are fairly minimal. That is, they don't try to do everything for me. Instead they help make a few common use cases easier and get out of my way otherwise.

This post wasn't really intended to say situations like yours are wrong, but rather I think it is a bad idea to just blanket-label ORMs as bad. ORMs themselves aren't bad, but when they are used improperly I have definitely seen things get out of hand very quickly.

A similar metaphor would be a knife - a knife in itself isn't bad. We all use them in our kitchen when cooking and have no issues. But if someone accidentally cuts off a finger how are we all going to react to it?

I think it is safe to assume that most of us won't run around saying "All knives are bad! Stop using them!", yet this appears to be what is happening in some Go communities with regards to ORMs and it is mostly a result of people hurting themselves when using an ORM in a past language like Django, Rails, or something else.

This post was meant to help illustrate what some of those pains are. To point out exactly how people are hurting themselves with ORMs, and how those issues could be avoided.