Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

People love to rant about ORMs.

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.



People who avoid ORMs endup writing their own worse ORM*. ORMs are perfect if you know how and when to uses them. They encapsulate a lot of the mind numbing work that comes with raw sql such as writing inserts for a 50 column database.


100%. I once tried to optimize a SQL query, moving away from the ORM, so I can have more control of the query structure and performance.

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.


I find that Claude writes boilerplate SQL very well, and is effectively an 'ORM' for me - I just get plain SQL for CRUD.

Complex queries I write myself anyway, so Claude fills the 'ORM' gap for me, leaving an easily understood project.


Writing is just half the job. Now try migrations, or even something as fundamental as ”find references” on a column name. No, grep is not sufficient, most tables have fields called ”id” or ”name”.


I did that once on a hobby project, accidentally. When I realized the corner I had painted myself into I abandoned it.


I'd say, pure SQL gives you a higher performance ceiling and a lower performance and security floor. It's one of these features / design decisions that require diligence and discipline to use well. Which usually does not scale well beyond small team sizes.

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.


The best is when you use an orm in standard ways throughout your project and can drop down to raw sql for edge things and performance critical sections… mmmmm. :chefs kiss:


100%

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 like Django's ORM for good schema migration. Other "ORMs" people build do not often have a good story around that. So often it's because developers aren't experiencing the best ORMs they could.


Homegrown ORMs are universally terrible and a lot of the anti ORM crowd are really anti homegrown ORM.

I’ve used Django, SQLalchemy and Hibernate. All three have good migration stories.


I think people should go all-in on either SQL or ORMs. The problems you described usually stem from people who come from the ORM world trying to write SQL, and invariably introducing SQL injection vulnerabilities because the ORM normally shields them from these risks. Or they end up trying to write their own pseudo-ORM in some misguided search for "clean code" and "DRY" but it leads to homegrown magic that's flaky.


In Java, the sweet spot is JDBCTemplate. Projects based on JDBCTemplate succeed effortlessly while teams muddle through JPA projects.

It is not that JPA is inherently bad, it's just that such projects lack strong technical leadership.


I believe jOOQ is Java's database "sweet spot". You still have to think and code in a SQL-ish fashion (its not trying to "hide" any complexity) but everything is typed and it's very easy to convert returned records to objects (or collections of objects).


Sir, sqlc for example.

I know exactly what's going on, while getting some level of idiocy protection (talking about wrong column names, etc).


Poor developers use tools poorly, film at 11.

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.


ORMs can be the starting point to optimize the queries when they need it manually with SQL.

There's also the reality that no two ORMs may be built to the same way and performance standard.


I'm wary of people who are against query builders in addition to ORMs. I don't think it's possible to build complicated search (multiple joins, searching by aggregates, chaining conditions together) without a query builder of some sort, whether it's homegrown or imported. Better to pull in a tool when it's needed than to leave your junior devs blindly mashing SQL together by hand.

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?


At least when I see raw sql I know me and the author are on a level playing field. I would rather deal with a directory full of sql statement that get run than some mysterious build tool that generates sql on the fly and thinks its smarter than me.

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.


You can use EF by writing the migrations yourself ("database first"). Also, whatever problem you have there seems to be easily fixed either by a better understanding of how EF's code generation works, or by more aggressive use of version control.


Their point is they understand sql and dbs. They shouldnt need to learn EF and all its footguns.


i think you should just create another migration with alter table that adds that column


all of this is solved by an sql query builder DSL


> - 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.

It’s really funny because you’re describing an ORM perfectly.


I don't know what kind of ORM you have used but I probably wouldn't like it either.

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.


They're making the tongue-in-cheek observation that those who don't use an ORM end up reinventing one, poorly.


A bad ORM. Every application that accesses an SQL database contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of an ORM.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: