A few weeks ago, I found out that a bit of transactional database logic was misbehaving. After lots of fiddling, debugging, and going WTF?!, like y...
For further actions, you may consider blocking this person and/or reporting abuse
OMG I have felt this way for years now about a lot of orms, well the 3 I have used (Django was another), but hibernate combined with spring plus jersey plus jax-rs plus javax.servlet 1.19 oh wait now I have to use 2.2, plus jetty for local but not jetty 8 because I had to switch to java 1.8 for something and so now I need jetty 9.2 but oh oops you arent using intellij jetty-runner I hope pal! There some bug so upgrade to 9.4 but then oh wait servlet standard 2.0 isn't working now in jetty, better say f-it and just ftp war file to aws instance oh thats better but then ohno wait now I have java 9 code from something wtf is osgi? wtf is asm? wtf is any of these 100s of dependencies???- thats a load of misery there, and then I really hope you didn't run this on wsl on windows because work makes you use windows and then you are running a windows intellij and a linux-kindof maven, OOPS!, and then I really hope you didn't have to wait until the last minute to upgrade the super old spring versions and swagger that your old boss who quit put in, and then someone upgraded bamboo to maven 3 and everything broke, and ......
it goes on from there. I am up at 3am for the 3rd week in a row trying to get this mess straightened out. It's a nightmare. This article gave me my first laugh in a week :D thank you and sorry for the rant
Hehe, I call this frustration driven development. First you get mad, then you fix it, and then you fix it properly. I recognize several of the things you are getting frustrated about (jersey is indeed a mess of dependencies). Tip, have less of that in your life and you'll feel better. In the case above, drop hibernate and it goes away. There's nothing it does that I need or miss in my life.
You inspired me to see if this could be done to "unlock" tables to a rest-interface on a more general level, and it can be done: github.com/fwi/db2rest
It is far from "feature complete" but that was not the point: while writing the source code the benefits you outline in your conclusion (ease of use, code that does what it says) started to become apparent. I think I will venture forward in this direction.
Thanks for this nice post, I have the same feelings about Hibernate. JDBC (we selected JDBI as a basic library) seems like relief compared to that.
I am currently trying to remove JPA/Hiberante, but I am faced with the problem of database schema initialization for unit tests. This task was solved by Hiberante which worked well with a H2 database. Without Hibernate, this database must be initialized some other way. The Flyway scripts that we use for the real MySQL database are not compatible with H2 (even with the H2's MySQL mode).
Have you found a way to initialize an embedded database for (unit) tests? How did you do that? Thanks.
I tend to use docker for database integration tests. I find embedded database performance is not really worth the feature differences. So fire up the real thing (or the closest thing to it). That also simplifies creating a database to just running the production schema and migrations and reduces the potential for weirdness related to (substantial) feature differences.
I can empathize with the frustrations of Hibernate. When I get to the point of: "OK, screw this, I need my native SQL, please." I tend to reach for jOOQ because I can get a much larger subset of SQL w/ clear, concise transactional semantics and the type-safe, SQL-like DSL that gives me that peace-of-mind about SQL injection. Since the DSL is code-generated during build time off of your schema, you get that extra layer of sturdiness by knowing at build-time (as opposed to at runtime, w/ string SQL) if your queries have invalid syntax. I'm not a jOOQ contributor, I just really like it.
Hey guys, greate post. I feel the same as you 😅 the main problem imho is the API. Its just too error prone and complex.
The learning curve is way too steep.
But its possible to create well performing applications, it just needs hibernate experts (hard too find 😆)
That‘s why i created spot-next.io. Its a framework based on hibernate, but fixes most of its problems.
I know it sounds weird, fixing hibernate by adding more layers on top 😂
But maybe you are curious and wanna try it out? Feedback is very welcome.
At this point I'm using Kotlin. Basically hibernate doesn't solve any problem I have, creates a huge potential for problems, I definitely don't need, all while trying to solve things that are definitely not problems in a way that creates more problems than it is worth.
Hey Jilles.
We've been doing a fair bit of content recently over on TheServerSide about Hibernate and JDBC and was wondering if you might be interested in reprising the thoughts expressed here into an article we could publish on the site? I know the JPA vs JDBC vs Spring JDBC exactly the type of thing our readership is struggling with.
@cameron , sure. Contact me at jilles AT jillesvangurp.com to discuss further.
"I like code that does what it says."
I find JdbcTemplate / TransactionTemplate to be more procedural, so now you've got code that focuses on the HOW when if you use declarative transaction management and Hibernate right, the code focuses on the WHAT. Do it right and the latter is more readable, more maintainable. Do it wrong and... well, you found that out.
Your code needs to live for many more years and people other than yourself will need to work on it. I think your decision to drop Hibernate and declarative transaction management might be beneficial in the short term, but could bite you in the long term. You've introduced lots of boilerplate code that may have bugs (or others may inadvertently introduce them).
The point with declarative is that it is nice until it isn't and it breaks on you. I've cleaned up a fair amount of very misguided uses of the
@Transactional
annotation on several projects where people were using it as some sort of magical incantation on anything that looked like it might be doing anything with a database.TransactionTemplate has about the same amount of verbosity but it doesn't lie and it gives you explicit control. I consider this more maintainable. Also compile time type checking vs. runtime injection of code has certain advantages. Annotations are very opaque in what they actually cause to happen at run time. One rogue annotation can really ruin your day.
I'm not alone. The Spring people are rolling back a lot of their fondness for annotation based declarative magic in favor of using kotlin based functional DSLs. E.g. the kofu project gets rid of essentially all of them in Spring Boot without really increasing verbosity. There are a lot of benefits. Start up time improves, it's easier to use Graal (no reflection/aop magic), it's easier to debug (just command click the function names, set break points, etc.). And it does exactly what it says.
Currently kofu is labelled as experimental but it's clearly the way to go. No more magical proxies that break in completely non magical and convoluted ways.
I and many others feel your pain. I've also had many challenges with Hibernate and JPA in general and "upgraded" to JdbcTemplate.
God, this post is like a balm for the soul.....
Bravo!
Like a big warning to hibernate people.. good read...