5 ms·
I have quite the opposite experience: you start with an ORM because your app is a simple CRUD, later when the app becomes more complex and the team/userbase gro
by kgeist 4y ago
I have quite the opposite experience: you start with an ORM because your app is a simple CRUD, later when the app becomes more complex and the team/userbase grow, you start having problems:
- N+1 query problem leading to subpar performance (down to unusable)
- escape hatches in the form of raw SQL increase cognitive load (2 ways to do the same thing, having to always remember how ORM matches to SQL and back when writing business logic) and may introduce inconsistency/bugs when the ORM caches object state in memory while raw SQL doesn't and you accidentally mix the two in one request (we've had a few such bugs)
- ORMs often encourage coupling business logic with DB access logic so it becomes harder to write tests and refactor code
- with a large amount of data (millions/billions of rows), built-in ORM stuff stops working when you care about zero-downtime migrations (i.e. no table locking, support for custom sharding etc.) so you end up writing cutom tools tailored for your use cases anyway
- it's harder to debug because there's a lot of magic
Our product was initially written using ORM and we ended up rewriting it using layered architecture, DDD and CQRS, it's much easier to reason about now (because all DB access is encapsulated in one place and doesn't spill over the rest of the application), and we're in the process of moving away from ORM in our CRM as well. I don't find it that hard to write raw SQL when implementing repositories and query services in the infrastructure layer, it's mostly write-and-forget for me.
- imtringued 4y ago>- N+1 query problem leading to subpar performance (down to unusable) There are two problems in hibernate. The join fetch syntax is pointlessly verbose. This means doing the right thing can turn a beautiful 7 line query into a 21 line monster as you constantly have to thread the same IDs back into the query. I mean it doesn't take many brain cells to do this: select member from Member member left join fetch member.groups groups where member in (:members) order by member.fullname; except you have to repeat this for every single relation but hardly anyone is aware of it and it is highly inconvenient so it isn't done by default. Other ORMs usually provide some sort of .includes() or .with() call which makes it less painful but even those could probably do with implementing a batching select fetch mode. The 1+N problem is mostly the result of bad default behavior because it "always works". Honestly I would prefer it if lazy loading was disabled by default and unloaded relations just give you an uninitialized error the moment you access them so you know you should fix your query instead of blaming the tool. The other problem is absurdly janky handling of inheritance where it just goes straight back to 1+N. I would recommend to simply not use inheritance with discriminators. The feature basically doesn't work if you don't have a 1:1 mapping of discriminators to subclasses. You can now say ORMs are like the Vietnam war or you accept that the way you are using the tool is extremely counterproductive. I mean I have seen code bases where the discriminator is converted via a case statement and hibernate simply doesn't know what the heck to do with that. Another problem with ORMs is their absurdly bad support for arbitrarily complex computed properties. CTE/WITH are not some arcane construct but the @Formula support in hibernate doesn't use them which means computed properties have unusably bad performance. From my perspective 90% of the ORM performance problems could be solved and in theory the ORM could even provide enough batch operation features to make your code faster than not using an ORM.
- capitainenemo 4y agoThis is a debate that has been going on for decades, but I rather like the point made here: http://www.revision-zero.org/orm-haters-do-get-it http://www.revision-zero.org/orm-haters-do-get-it "You simply can't use an ORM the right way You can use them in the intended way but unfortunately there is no right way. The reason is that the ORM approach is intrinsically flawed. This is the claim I'd like to discuss today." It's a short and interesting read so would like to see others take on his fundamental argument. It kind of reminds of me of kyren's Rust keynote and the difficulty of shoehorning OOP into places it doesn't really fit. https://kyren.github.io/2018/09/14/rustconf-talk.html https://kyren.github.io/2018/09/14/rustconf-talk.html