Personally, from the database-ops side, I know how to read quite a few ORMs by now and what queries they result in. I'd rather point out a missing annotation in some Spring Data Repository or suggest a better access pattern (because I've seen a lot of those, and how those are fixed) than dig through what you describe.
On the other hand, I agree that mapping SQL results to instances of shared models is not always desirable. Why do you need to load a whole user object when you want to display someone's initials and/or profile picture? And if you're not loading the whole thing, then why should this limited data be an instance of a class with methods that let you send a password reset email or request a GDPR deletion?
I know exactly what's going on, while getting some level of idiocy protection (talking about wrong column names, etc).
It is not that JPA is inherently bad, it's just that such projects lack strong technical leadership.
>- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.
It’s really funny because you’re describing an ORM perfectly.
My ORM does extremely much more than those "SQL helper" classes and it logs SQL nicely to the console or wherever I ask it to to log.
And it is easy to find it, just search for @Entity.
I poorly implemented SOLID design principles, creating a complete mess of a SQL Factory, which made it impossible to reason about the query unless I had a debugger running and called the API directly.
Complex queries I write myself anyway, so Claude fills the 'ORM' gap for me, leaving an easily understood project.
But seriously, yeah, every time I see a complaint about ORMs, I have to wonder if they ever wrote code on an "average team" that had some poor developers on it that didn't use ORMs. The problems, as you describe them, inevitably are worse.
For example, I'm working on a project right now where I have to do a database migration. The project uses c# entity framework, I made a migration to create a table, realized I forgot a column, deleted the table and tried to start from scratch. For whatever reason, entity framework refuses to let go of the memory of the original table and will create migrations to restore the original table. I hate this so much.
There's also the reality that no two ORMs may be built to the same way and performance standard.
If a dev thinks that all SQL can be written by hand then they probably haven’t worked with a complex application that relies on complex data.
A good question to ask them is: what problems do ORMs solve? Good answers are:
Schema Changes + migration
Security
Code Traceability (I have a DB field, where is it used)
Code Readability
Standardisation - easy hiring.
Separation of data layer logic and application layer logic.
Code organisation, most ORMs make you put methods that act on a table in a sensible place.
I’ve used Django, SQLalchemy and Hibernate. All three have good migration stories.
But as someone who writes both raw SQL and uses ORMs regularly, I treat a business project that doesn’t use an ORM as a bit of a red flag.
Here’s what I often see in those setups (sometimes just one or two, but usually at least one):
- SQL queries strung together with user-controllable variables — wide open to SQL injection. (Not even surprised anymore when form fields go straight into the query.)
- No clear separation of concerns — data access logic scattered everywhere like confetti.
- Some homegrown “SQL helper” that saves you from writing SELECT *, but now makes it a puzzle to reconstruct a basic query in a database
- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.
In short: I’m not anti-SQL, but I am vary of people who think they need hand-write everything in every application including small ones with a 5 - 50 simultaneous users.