Live data from Hacker News

To ORM or Not to ORM

eli.thegreenplace.net

221–230 of 300 posts

Re: To ORM or Not to ORM

#221

The ORM discussion reminds me of something Rich Hickey said in his talk, “Simple Made Easy”. He distinguished between “simple” (when a system is inherently low in complexity) and “easy” (when a system is made more complex so it is theoretically easier to use). ORM’s are easy, but not simple. If your system uses a relational database but not an ORM, you have to understand your particular database and also SQL to under…

> ORM's are easy but not simple. ORM libraries may not be simple, but what matters is the code that uses them. My experience was that the main code was often easier and simpler. Easier because small tasks are made easy. Simpler because it makes the code more consistent: for instance, once you know the ORM, you don't have to deal with hundreds of specific cases that insert or update various records. Promoting stored p…

> Simpler because it makes the code more consistent: for instance, once you know the ORM, you don't have to deal with hundreds of specific cases that insert or update various records.

That's not what 'simpler' means in this context. Simpler means conceptually independent things aren't coupled together. For example, ORMs couple together object-oriented code and relational objects. That's the essential complexity that they introduce.

> There is no canonical way to keep them in sync with the code.

There's still the old-fashioned way of checking them into the repo as part of migrations.

> They are vendor-specific.

Most people will almost certainly stay with a single vendor anyway. If you never take advantage of your platform for fear that you'll migrate away from it, you're throwing away a lot of potential benefits for some perceived future risk.

> As far as I know, you need to learn specific tools to debug them or to analyze their performance.

No more than you would with an ORM–in fact, with an ORM you'd need to learn two different stacks to tune performance or troubleshoot.

Re: To ORM or Not to ORM

#222
post #208

Earlier quoted context omitted.

Would that be a "RRM" (Record-Relational mapper)? If so we're already on board (in a different language). P.S. I bet you would never guess which typed language with great support for records makes it easy (for the most part) to build most type-safe SQL queries on the fly, even with projections, without explicitly defining types for every possible projection variation.

Would you happen to be talking about TypeScript?

yes

Re: To ORM or Not to ORM

#223
post #173

In my experience ORM always shoots you in the foot when your use case exceeds what an ORM can provide. ActiveRecord has been a terrible mess for us because the facade masks the underlying behavior (transactional behavior) or often doesn't do what it advertises (commit hooks, timestamps, auto-increment). ORM is great for startups trying to build out an MVP, but beyond that scale it's an anti-pattern. The best solution…

I came here to say that any article discussing the benefits/downsides of ORMs should include JOOQ. It takes such an interesting spot in the design space: not an ORM, but a super flexible, type-safe query builder with lots of helpers so you dont write more code than necessary.

In JavaScript there’s Knex which is a query builder that’s pretty good and has a few ORMs built on top of it.

Re: To ORM or Not to ORM

#224
post #153

Earlier quoted context omitted.

+1 for Hibernate. Everyone starts out hating it. The learning curve is steep and unforgiving. But it can do roughly everything SQL can plus everything you would want from an ORM. For the few that actually read the manual, there's strongly typed Criteria queries that have the full power of HQL. Which is basically DB agnostic SQL with a few really advanced features removed. There's also lazy loaded collections, caching…

LOL, I love the way you describe that... "for the few that actually read the manual". That has basically been my experience as well, and the ones that complain the loudest are the ones that refuse to read and understand what is actually happening. I've also run into a lot of people that loved it at first and then hated it when it first went into production because they didn't read the manual and didn't pay attention…

Yes absolutely.

Hibernate is a microcosm of Java. If you read the manual things are fine, but it's not designed to be "wingable". It abstracts away enough of the DB that you need to understand the magic or you'll make massive blunders that haunt you later.

Given that maybe 10% of devs read the manual for anything after leaving school there's a lot of Java and Hibernate haters

Re: To ORM or Not to ORM

#225
post #100
post #49

I put a ton of work into an ORM that statically typed SQL a couple years ago. I always thought this would be a cool way to go. https://github.com/rspeele/Rezoom.SQL/ But I never got to use it at work, and thus lost interest. The biggest thing missing with it was that you lost type safety if you had to dynamically build a query. These days its main problem is lack of compatibility with .NET Core, which somebody else w…

Great work. I used rezoom in couple of minor projects and like most that I could really trust that query runs if it compiles. Unlike in Entity Framework where you have unlimited possiblities write code which compiles just fine but crash runtime. In principle I don't like an idea that your primary language get compiled to SQL due it's very leaky abstraction. Instead I like expressing queries as data (ideally compile t…

Thanks. I agree composition was a pain point. I had various ideas to make things better, like adding support for "erased" views/functions/TVFs that would be inlined at compile time, but it always felt like it'd be hacky and still not solve enough problems.

Type providers are such a cool language feature, but the way developing one works is too damn confusing. Especially when you try to publish one as an easy-to-use package and simple stuff like loading dependencies feels like uncharted territory. When it comes to my precious free time I hate, hate, hate figuring out packaging/deployment type stuff, I just want to focus on my code. So that's a big part of why I haven't done a great job maintaining it.

Re: To ORM or Not to ORM

#226

I am quite disappointed that both the article and the comments dont mention application security. USE AN ORM. Unless you are a hotshot SQL dev who knows the intricacies of every RDBMS, you should be delegating this to the ORM. Its there to prevent you from blowing your foot off by introducing SQLi vectors. Use an ORM, avoid SQLi.

Using an ORM to enforce security is like wearing your motorbike helmet down to the store in case a bird shits on your head.

Yes, it will help prevent bad developers from introducing sql injection vectors, but with a whole lot of extra baggage coming along for the ride.

And there are other application security scenarios involving database where the ORM gives you nothing, such as always forcing a "tenant = " filter in a SaaS scenario (which some database engines do support).

Re: To ORM or Not to ORM

#227
post #169

Earlier quoted context omitted.

+1 for Hibernate. Everyone starts out hating it. The learning curve is steep and unforgiving. But it can do roughly everything SQL can plus everything you would want from an ORM. For the few that actually read the manual, there's strongly typed Criteria queries that have the full power of HQL. Which is basically DB agnostic SQL with a few really advanced features removed. There's also lazy loaded collections, caching…

I'm still at the "hating it" stage, but most of my Hibernate experience has been with older versions of Java (5 & 6), or with trying to deal with other people's HQL sprinkled all over. It's a lot of rope to hang one's self with, IMO. Not that native SQL isn't, but there's something to be said for an enforced separation of concerns that I feel like Hibernate breaks a little too often.

My most useful suggestions to less hate:

Turn on the MetaModel code generation stuff. Use Criteria with strongly typed queries for everything that's not a simple find. Much less potential mistakes in combination with validation.

Always turn on HBM2DDL validation! Without this you won't know if there's a problem between entity->table mappings until a query explodes.

For the same reason, don't use HQL or Raw DB queries. You lose training wheels Hibernate is meant to give. In the same vein always use MetaModel strongly typed Criteria .get() syntax. Column/table name strings are evil, you lose type safety.

Turn on collection lazy loading. Otherwise N+1 queries will be everywhere. Beware future detatch() advice when doing this, you will need to trigger the load before detaching if you want that collection to be there.

Use a JDBC proxy to monitor for slow transactions and pretty print generated SQL if needed.

Be very careful with Hibernate lifecycle. It normally returns object proxies, the objects it returns to you are not of your actual class. They have magic in them that can explode if you continue to pass the POJO around after the transaction is complete or session flushed. Rule of thumb, detatch any entity you're passing to a different method.

Again with lifecycle... Be aware that asking for the same object twice will not give you a copy. It will give you the same object! Reference and all! This is another reason to detatch. You don't want people modifying POJO's built by Hibernate, they're magically linked to actual DB data.

Use Identity Type = Sequence. It's less dumb than normal auto-increment PK

Never use your entity classes directly in REST endpoints. You're in for a world of pain when refacgoring DB columns when it also changes your endpoints. Use something like MapStruct to map your entities to DTO easily.

Use Lombok to greatly reduce the POJO insanity of entity classes.

Be very very careful with session.clear() . Unless you 110% understand it, don't use it.

Be careful when trying to serialize hibernate entities. If you have a circular reference between two entities (bidirectional parent child for instance), Jackson and GSON will recurse infinitely. To prevent this, use their annotations to prevent serializing in the direction that makes less sense. Mapping to MapStruct DTO's before REST will allow you to directly prevent this.

For things like PK, use primitive types to prevent hibernate from inserting nulls. This is kinda a hack, but nice if 0 is an acceptable default value which it often is.

Enable code generation style dirty checking. Otherwise, for checking whether child collections and such have been altered hibernate will call .equal(), which nobody ever implements correctly (or at all). Better to use code generation dirty checking mode so hibernate can use magic to check fields for you.

Be aware that hibernate doesn't care if FK's or indexes exist. If you want things to run at realistic speeds, you still need to make these yourself.

We managed to make our entire app, with about 110 REST endpoints, entirely strongly typed Criteria queries. Not a single line that isn't DB agnostic or bypasses hibernate. Trust me, things are much better this way. Once you cross the barrier nothing is certain.

There's more, I should probably write a blog post instead of novels on HN

Re: To ORM or Not to ORM

#228
post #20

I wish people did not think the choice was solely between "write raw SQL with raw strings" and "try to pretend the database is object-oriented when it is not." The third approach is to safely wrap the database and its columns with code in a way that is composable. In Python, SQLAlchemy has an ORM, but it is optional, and you can just work with tables and columns if you want.

For a long time these were the main choices and the third way had very little library support and generally required you to role your own, which were generally crappy and inefficient. Even when "lightweight ORM's" were first gaining traction their composability was quite poor (and some ways it still is) and would often leave the denormalisation part to the application.

Even though I think this third way should be the "default" way to write an application now there's an awful lot of code left over from when an ORM was better.

Re: To ORM or Not to ORM

#229

I've come to a couple conclusions, over the years. First, when you get down to it, the most-valued feature of ORMs is not the "writing queries in some language other than SQL" feature, it's the "not having to write a mess of mapping code" feature. Second, the biggest drawbacks to ORMs all derive from the "writing queries in some language other than SQL" feature. Fortunately, there are tools out there that solve the "…

Full featured ORMs also provide migrations support - which can be nice to have. You mention Dapper, which I like. But if I were working on a .NET codebase I like the idea of using EF for basic CRUD + migrations, then Dapper for non trivial SQL (everything else).

Re: To ORM or Not to ORM

#230
post #189
post #69

Earlier quoted context omitted.

Yeah if you’re doing lots of CRUD that approach quickly becomes an exercise in writing your own (bad, buggy) ORM.

Not at all. The only cumbersome thing about SQL, that is common enough and unpleasant to always spell out by hand are basic INSERT and UPDATE commands. I use a set of 3-4 functions that I reuse pretty much in all my programs for this. It's no ORM, as it doesn't map classes to tables/data in the database. It's just a shortcut to generate and execute INSERT/UPDATE commands on arbitrary tables with arbitrary columns. Al…

> you can hardly create bugs in something so simple.

You may have underestimated how bad things are in some of the unicorns..

1. Creating your own query builder before understanding the purpose of bind param: https://medium.com/tokopedia-engineering/dynamic-sql-query-b...

2. ???

3. Profit from SQL injection: https://www.youtube.com/watch?v=PKkNjOweWTE

Post reply on HN