How Hibernate Almost Ruined My Career
The idea of "use Hibernate so you don't have to write SQL" while being objectively wrong, also hits on an antipattern I've noticed over and over again. The "- so you don't have to -" anti pattern. Such as "we will configire this in xml so you don't have to write more code". Or "put some code in the database so you don't have to do a deployment process to make changes."
You always end up having to do the thing you were trying to avoid plus deal with the middleman abstraction you introduced trying to avoid it. Anytime I hear someone say "- so you don't have to -" I wince and anticipate upcoming technical debt.
Hibernate didn't ruin his career, SQL did. If he'd actually worked with Hibernate, rather than abandoning it for SQL at the first opportunity, he would have got a system that performed well for less effort, was database-independent (which makes it easier to e.g. have a better test suite, because you have a wealth of in-memory options for testing so you can afford to run more tests on each build) and was more maintainable. All too often I've seen it play out like this:
1. Hibernate system working great
2. Idiot notices that one of their queries is slow, blames Hibernate
3. Idiot writes their query in raw SQL because hurr durr SQL is faster than Hibernate. (Bonus points for never benchmarking anything. Extra bonus points for switching to SQL and adding an index at the same time, observing this makes it faster, and deciding it's probably the switch to SQL that made the difference)
4. Idiot notices their query is getting results that are inconsistent with recent changes that went via Hibernate.
5. Rather than making any effort to fix this properly, idiot disables all caching in Hibernate. There, I fixed it.
6. Idiot notices that Hibernate queries are now slow (gee, ya think?) and uses this as a reason to migrate all other queries to raw SQL.
Hibernate doesn't save you from having to design a good data model, nor from having to tune it for performance. You can't turn off your brain when using Hibernate, you do still have to figure out which entities own which side of their relationships, and when you get to a scale where performance becomes an issue you do have to spend a bit of time doing performance tuning, just as you do when using SQL. It does genuinely simplify a lot of things and save you from writing a lot of boilerplate. But if you spend a week tuning your SQL query and no time tuning your Hibernate query and use that as your benchmark, no shit the SQL will be faster, and if your first resort whenever you hit a slow query is going to be to bypass Hibernate rather than working with it then yeah you probably shouldn't be using Hibernate in the first place.
> We’re always struggling with lazy/eager fetching problems. At one point, we decided to do everything eagerly, but it seems suboptimal, and besides, sometimes it’s not possible to access some fields because there is no session, or something like that. Is that normal?
WTF. No concept of the N+1 problem.
> We’re still struggling with which database engine to use for the final deployment. I thought Hibernate was portable, but we have some native queries that use some MS SQL magic, and we’d actually like to go with MySQL in the production
WTF. Why are you developing against MS-SQL then?
> Sometimes we spend days looking for errors. It seems like we have to analyze Hibernate-generated SQL because we have no idea why it’s not working as expected and it’s producing unexpected results.
WTF. If you don't understand your ORM you won't understand the queries it generates.
> Can you help me understand how Hibernate cache works? I just don’t get it. There are some first/second level caches. What is this all about?
WTF. No concept of using transactions.
I've used ORMs longer than the term ORM existed. I've never once thought it as a replacement for SQL. It's a supplemental tool.
I used to think I needed to learn an ORM to be able to write maintainable software.
However time taught me writing maintainable SQL with good migration story is way better. ORMs make porting queries to another project that needs to use the same database difficult. It's less obvious what is really happening and the performance usually isn't as good as hand written SQL. Hand written SQL also means fine grained control over prepared queries, access to vendor specific features (advisory locks, LISTEN/NOTIFY, triggers), materialised views etc.
You could argue these should be domain of DBA but in my opinion all devs should atleast know SQL at this level.
Straw man script about what happens when you "blindly use Hibernate." I suppose there are lots of people in the world who do that. I would think that Hibernate isn't the sole problem in those cases.
I suggest a better title for that article: "How I blame technology X of almost ruining my career when I am the only one to blame because I did not understand what I was doing"
This doesn't look like it was a problem with Hibenrate, more of a "wrong tool for the job"-scenario. Reposting what I recently wrote on Reddit on a similar Hibernate discussion thread:
In my experience, ORMs and specifically SpringData-JPA-Hibernate occupy this weird niche in the enterprise spectrum. They are an overkill for small projects and they become a hinderance for large projects, so they sort of sit there for medium projects. If you start with an ORM on a medium size project and it becomes a big project you can sometimes find yourself in an awkward spot where you are writing a lot of SQL (and not of the JPQL kind). With Hibernate/JPA specifically there are so many things that are broken that they just start getting in the way if your schemas become large enough. To me this is really just a manifestation of Behavioral Problem (Martin Fowler, Enterprise Patterns), where relational databases don't really map to objects at all when you get down to it.
Basically, if you are going to do quite a bit of SQL, any ORM will just in the way. Should be plainly obvious to anyone with experience.
I don't understand why SQL is avoided so much. Yes it can be a pain to get/transform types depending on the driver/adapter, but to me that's the whole of a thin wrapper. SQL is just code, not another API to learn, is typically just as self explanatory if not more, let's you use vendor-specific features easily, removes any voodoo so it's clearer what's going on, and isn't that hard to begin with.
Look, if you write clear sql anyone will be able to read it. ANSI sql can be read by people even from other languages. You need to wrap it layers of bizarre abstraction and tape on language specific orms. How else will you keep your job?
This article: http://blogs.tedneward.com/post/the-vietnam-of-computer-scie... is 10 yrs old. It is clear and to the point. ORM is a bad choice. Take a little time to Learn SQL basics, it is easier than any programming language.
I supported a deals site that used Hibernate with JBoss. We went through several years of scaling pain until a consulting engineer found that the Hibernate cache settings were left at their defaults.
Frankly, I've never understood the real-world utility of ORMs such as Hibernate. As far as I can tell, their purpose is to "abstract away" a database. But why?
SQL isn't hard. Learning database optimization is nontrivial but doable for anyone. Why do we need ORMs? Why is it better to replace a "WHERE ..." clause with ".where(...)"?
My personal impression is that these frameworks were developed for people that know how to write code in some language but don't know how databases work and want something easy instead of learning how databases work. It really feels very lazy to me.
If you have a library or framework thatproperly prevents SQL injection attacks, why use an ORM unless you feel too lazy or scared to learn how to use a database properly?
If you need to map relational database to objects and don't use an ORM, you will eventually reinvent it, in a bad ugly and buggy way. ORM is hard. Hibernate is a fantastic robust thoroughly tested and massively successful framework. But as any power tool, in the wrong hands can be a disaster.
For our API, I've rewritten probably 2/3 of the public endpoints to use raw SQL. I'd like to rewrite the other apps as well. The non-ORM app has no issues whatsoever. I estimate probably an eighth to a quarter of the time I've spent in the last three years has been dealing with completely avoidable ORM issues. Yeah, I can relate. At least it wasn't my choice to use them. It's a minor consolation.
Shameless plug: if you're looking for a no-dependencies Java 8 JDBC wrapper, we have been using https://github.com/pyranid/pyranid in production for a number of public-facing projects over a couple years and it has worked very well for us
> I had to learn Hibernate architecture, configuration, logging, naming strategies, tuplizers, entity name resolvers, enhanced identifier generators, identifier generator optimization, union-subclasses, XDoclet markup, bidirectional associations with indexed collections, ternary associations, idbag, mixing implicit polymorphism with other inheritance mappings, replicating object between two different datastores, detached objects and automatic versioning, connection release modes, stateless session interface, taxonomy of collection persistence, cache levels, lazy or eager fetching and many, many more.
Welcome to Java …
I generally find that an ORM makes easy things easy and difficult things indescribably hard or impossible. Honestly, the relational model is great, and it's worth understanding well. Frankly, if you're a software developer and you can't learn SQL … you're not really a software developer.
Maybe this is out of inexperience, but having worked with Rails' and Django's respective ORMs, some of the things, about Hibernate, from this article like, lacking migration support seem a bit strange. And never having used it, feel like I am not seeing the complete picture.
Anyone with having worked with both, care commenting ?
In this story, Monica was able to actually get to year 4. What's to say that if she went with raw SQL, the team never would have been productive enough to match their run rate. For every story there is of a successful team who rues using an ORM, how many teams are out there who are lost to the obscurity of failure thanks to not choosing a fast over correct solution.
Now, this is not a judgment for or against SQL, given there are plenty of users of Hibernate, it has clearly worked for some teams. Equally, given people still write SQL, I am sure it has worked for many people.
Fundamentally there are two questions to my post:
1 - how much could have been saved in this scenario by a better team
2 - how often is it that the right solution now becomes the wrong solution later?
> Software Architect
I found the problem.
A long time ago, in a programming language now forgotten (gosu) some interns and I created a SQL typeloader that allowed you to define your domain in SQL DDL files and then write query files in SQL that were accessible, type safe, directly from Gosu:
https://github.com/gosu-lang/ragnardb
https://github.com/gosu-lang/ragnardb-test
No codegen, just made SQL resources a top level type safe resource you could work with.
I liked the idea a lot.
Having built my own ORM and my own distributed key/value JSON store with index over HTTP I can say SQL is the problem, SQL databases are older than the internet, they have not evolved since the 70s. You need async on the network preferably over HTTP (to be client agnostic) and almost no database provides that today. Heck no programming language provides multi threaded non blocking IO with shared memory, only C++ (and maybe modern attempts Rust, Go, Swift etc.) and Java (C#) are capable languages.
A major red flag is if you hear any developers saying things like: "The ORM will abstract access to the database so that it's like everything's in memory."
"To get a report, we have to wait two days!"
Who in their right mind would use Hibernate (or any other ORM for that matter) for reporting?
Why does SQLAlchemy feel so much nicer than Hibernate? Is there something equivalent in the Java world?
I knew that ORMs where a bad idea since the first time I saw one many years ago. It never made any sense to me. I don't see how they simplify anything; even in the early stages. SQL is actually a really simple abstraction for fetching relational data.
Currently dealing with a simple user database in a backend, Play Framework (Java) for a website. After reading this I'm worried doing this with EBean ORM is not good. Any advice/comments from experts?
This page will serve as a very useful "Who not to hire" page.
"ORM" means "snake" in Swedish, and will bite you.
Does Java not have a good Micro ORMs (like Dapper, NPoco on the .Net side)? They can be a wonderful middle ground between completely custom sql and a full blown giant like Hibernate.
I'm using scala Slick for huula, should I have this concern too since the development there seems really like just a one company effort.
Java circa 2005 had a whole lot of problems, but if you ask me, the biggest problem of it all was that many of the 'solutions' to the problems were worse than the disease.
Back in the day, a friend of mine brought me in to write business software in Java for a small retail company. They didn't have much money, but they also didn't have any management that cared about our technical decisions, so we had a freedom that helped our careers tremendously: Nobody is making any less than 3x what they did then. But along with that freedom came the responsibility of getting the decisions right.
Hibernate was a great improvement over the awfulness that was naked JDBC, but the risks to bad performance were so terrible that we ended up just writing some decorators to make JDBC usable instead. Years later, I went to a big enterprise place, and saw what happens when developers stop learning SQL, and use hibernate to run complex queries.... and then I learned how big of a bullet we dodged.
Hibernate wasn't the only bullet though: One that Java is still suffering from is Spring. We decided that exchanging boilerplate you compile for XML was not a good tradeoff. Later they added annotations, but still, handing all of that wiring to the runtime is just not a good idea. Spring also taught people that it's easy to just have objects that can be constructed in ways that are broken (zero param constructors were easier to use), made application startup slower than even EJB, produce error messages that make the Clojure compiler seem friendly, and added all kinds of insane nonsense that made Rod Johnson quite rich, but didn't help Java itself move forward. Java 1.4 and java 5, out of the box, are like a person with a broken femur. Instead of fixing the bone, most of the ecosystem was just feeding the patient oxycodone: The result was that the patient still had a broken bone that was setting incorrectly, and the patient was now addicted to opiates. And yet, the people that wrote the bad tools that caused this have nice houses in Nob Hill and get to try to build new startups, now selling us their magical solution to the microservice problem.
The Java ecosystem only started to move forward when Ruby on Rails came to town, and, despite all of it's own problems, made it clear that the whole thing had to move forward. Now the JVM has far better languages than Java, and Java itself has actually improved in important ways, but that was due to competition, not bad solutions to problems.
I think we are back in the same boat with NoSQL databases: The companies selling tooling that did well didn't do so on good engineering, while the companies that did the best engineering struggle. But is the whole movement a good idea, or are we just going to see something like Spanner come in and the technologies that people got so excited about were just low quality solutions to problems that most of the time we didn't even have?
I think there's more to learn from the pattern of how developer tools succeed (and fail to deliver), than from just the lesson of Hibernate's tremendous shortcomings for anything complicated.
I think ORMs are fine for greenfield CRUD apps done with code-first. SQL is the assembly language of the backend.
SQL is an amazing and very useful tool to work with. I will never understand why people want to abstract it away.
I used to think I needed to learn an ORM to be able to write maintainable software.
However time taught me writing maintainable SQL with good migration story is way better. ORMs make porting queries to another project that needs to use the same database difficult. It's less obvious what is really happening and the performance usually isn't as good as hand written SQL. Hand written SQL also means fine grained control over prepared queries, access to vendor specific features (advisory locks, LISTEN/NOTIFY, triggers), materialised views etc.
You could argue these should be domain of DBA but in my opinion all devs should atleast know SQL at this level.