Live data from Hacker News

Problems with JPA/Hibernate

stemlaur.com

151–160 of 195 posts

Re: Problems with JPA/Hibernate

#151

Everyone hates JPA/Hibernate, but what’s the alternative? I’ve seen this a few times. “You don’t need an ORM, write your own SQL queries directly and create a beautiful domain driven design object model” leads straight into a project only the owner will understand. Homegrown mini-ORM that’s full of pitfalls, inconsistent object model, hacks and TODOs all over the place. If you’re living in the Java ecosystem, the big…

C# have micro-ORMs like Dapper, surely Java has smth similar? Micro-ORMs show the SQL but the object generation still gets done for you so you get a bit of both worlds.

I wouldn't call it micro, but https://ebean.io/ is pretty nice.

Re: Problems with JPA/Hibernate

#152
post #96

Earlier quoted context omitted.

Scala/Kotlin have some SQL abstraction libraries which have immutable data entities, actual constructors, etc. So I don't see why any of this has anything to do with SQL rather than the limitations of Java and Hibernate trying to force Java to do something it's not designed for.

SQL abstraction libraries yes. ORMs, not really. You can map between an immutable datatype and the state of a row at a given point in time, but the only natural way to work with the native way that SQL databases express writes - in-place updates to rows - is with a model that represents them as in-place updates. In my experience those SQL abstraction libraries tend to be oriented towards either thinking in a purely c…

> the only natural way to work with the native way that SQL databases express writes - in-place updates to rows - is with a model that represents them as in-place updates

I strongly disagree with this for a few reasons. I actually think the command-oriented way is makes the most sense. The problem with in place updates is that:

- Your queries aren't views. What you queried out of the DB is a snapshot of what is in there. It may already be different. - The way you interact with a DB is command based. If you want to update a row that is a command that may fail.

The only way I feel that using mutable data would make sense is if you had some sort of 2-way syncing. But those are notoriously difficult to get right even without network trips in the middle.

Re: Problems with JPA/Hibernate

#153
This post reminds me of what happened some weeks ago at my job.

We use Clojure and yesql (a library where you write sql queries directly in .sql files and the library generates functions for you). The devops noticed one of our queries was slow and taking too much DB resources. He sent us the query which we promptly found and then asked us if we could change it to a more performant version he just wrote.

We took his query, just replaced in our sql file and deployed. 10 minutes later he came back saying things look much better and the query update really helped.

I wonder how much time it would take if we were using JPA/Hibernate as we used to, many years ago.

Re: Problems with JPA/Hibernate

#154
A default constructor must be present, yes, but if you use Kotlin a compiler plugin can generate this constructor that is not visible in your code base (but would be if another module would use the compiled byte code).

JPA/Hibernate does not require getters and setters. Fields can be used directly for ages (more than 10 years).

The arguments against reflection are pseudo arguments, because the developer doesn't use reflection himself where usual programming language means would be better. Instead the framework uses reflection to free the developer from writing boilerplate code - completely different things!

The claim that it would be impossible to return unmodified collections because one would be forced to provider getters and setters is wrong. If Hibernate uses the fields directly, it is no problem to give only an unmodifiable view of a collection to the outside.

I don't see a general problem with lazy loading. You have to understand what you're doing, but that should be the case with every framework. Hibernate is quite flexible with eager and lazy loading and it is possible to specify an entity graph per use case to say Hibernate what to load eagerly and what not. Another possible is to use dedicated query objects (usual entity classes mapped to the same table, but designed for a certain use case).

The section about "Accessing a single table field" ignores the fact that the object mapped with Hibernate could also only use the needed fields. You could even select a single value with JPQL without any domain class involved. This argument is kind of dumb and wrong.

"Constraints" with Bean Validation are not a core part of Hibernate and shouldn't really be in this article. But, as they are already there, let me say that the criticized "too late" enforcement of the specified constraints is only the default behavior (because Hibernate can not know when to perform the check). Nothing prevents you from performing these checks explicitly with the means of the Bean Validation API. But apart from that, I'd prefer to write this kind of rules as usual code, too.

"Framework updates are horrible": I had never a severe problem switching to a new Hibernate version. Same is true for Spring (but wait, why does this article mention Spring at all?).

"Rename your JPA Repositories to JPA DAOs": The author doesn't understand the difference between a DAO and a Repository. A repository is at the same level as an entity or value object, it _is_ a domain concept. BUT the implementation of the repository interface is indeed part of the infrastructure, but this implementation would reside in another package. There is no need to name "repositories" always "repository" - if you want to name the class "BankAccounts" then do so! By the way: the class name "BankAccountsJPAImpl" is a crime!

The advice to generate IDs in your own implementation is kind of silly. "if an id is generated, it should be done knowingly" Why? Usually an ID is just a number with no special meaning other than being unique per entity type. Even if you'd decide to drop relational databases and use advanced CSV files instead the sequence number generation could easily be implemented then. And why on earth should one want to test the sequence number generation? I trust every solid database to be able to generate perfectly fine sequence numbers!

The section "Stop adding multi-directional association" has nothing to do with Hibernate specifically, because that is some kind of general design consideration.

One big question remains unanswered by this article: What is the alternative? The author implicitly suggests that it would be SQL. But things are not so simple. If you want to have a domain model (and not a mixture of domain logic and technical infrastructure), you not only have to load data from the database and create objects from it (the easy part), but you also need to find out what data needs to be written to the database after business operations were performed. I'm not aware of a simple solution here (but let me know ...). There are other things like optimistic locking where Hibernate simplifies things a lot.

All in all the article is not well balanced and flawed.

Re: Problems with JPA/Hibernate

#155

Earlier quoted context omitted.

That's why JOOQ is superior.

It depends on what you want to do. Complex queries with multiple joins? jOOQ. Persist changes to complex aggregate models with multiple layers of child entities? JPA/Hibernate.

> Doctor, it hurts when I do this. Then don't do that

Re: Problems with JPA/Hibernate

#156

Earlier quoted context omitted.

They made some concrete criticism based on their experience (hard to maintain, complex annotations, etc), but you in turn dismissed those with "you didn't get" and some borderline name-calling. Which bit they didn't get?

doctor_eval wrote: >> You get to throw away all the semantics built into the database structure, including knowledge about indexes, I wrote: > suggests you either don't know JPA very well or your writing is a bit sloppy. To suggest that JPA means "throw[ing] away all the semantics built into the database structure, including knowledge about indexes" indicates either that the person doesn't know what JPA is about: ind…

I don’t think my point was sloppily written, but perhaps you misunderstood it.

JPA is conceptually incapable of automatically utilising the structure of the underlying database (despite the fact that the database structure is actually dynamic), so it makes up for it by requiring you to write these huge entity models which declare - and duplicate - that structure. You effectively “throw away” the database structure because you have to rewrite it in Java/JPA. I mentioned indexes but that’s just a side issue.

One consequence of this is that it makes refactoring much harder; I found that Java side of a JPA refactor was way more effort than the underlying SQL refactor, but that really shouldn’t be the case.

Re: Problems with JPA/Hibernate

#157

Everyone hates JPA/Hibernate, but what’s the alternative? I’ve seen this a few times. “You don’t need an ORM, write your own SQL queries directly and create a beautiful domain driven design object model” leads straight into a project only the owner will understand. Homegrown mini-ORM that’s full of pitfalls, inconsistent object model, hacks and TODOs all over the place. If you’re living in the Java ecosystem, the big…

The interesting part is how to perform updates without an ORM. All this "just use SQL" statements seem to ignore this problem. If a domain model is used there is no simple, obvious way how to find out what needs to be updated in the database and how to generate performant SQL code from it. I'm really interested in some examples how to do it.

Re: Problems with JPA/Hibernate

#158

Earlier quoted context omitted.

I disagree on most of your points but I am trying to read your entire comment favorably, but my personal experiences do not line up with almost any of this. >>> JPA/Hibernate is still the best way to actually produce working applications if you have to use an SQL database for some reason... This statement makes me think that you either do not prefer to use SQL RDBMS, don’t have to use them very often, believe they ar…

> I expect every single one of my backend engineers (on any tech stack) to understand the fundamentals of SQL INSERT, UPDATE, and DELETE statements. Understanding INSERT, UPDATE, and DELETE doesn't help you very much when you have to persist changes to a single child entity of many in an aggregate (parent entity). How do you track which child has changed? Or if a new child is added? Or one is deleted? Or what if the…

Exactly this! And I'm curios to learn how to solve this update problem (in an elegant way) with pure SQL.

Re: Problems with JPA/Hibernate

#159

I solve Hibernate problems by using jOOQ instead. The migration more than paid off the couple times I did it.

How do you solve storing/updating/removing child entities of another entity (which also may be a child of another entity) effectively? I use jOOQ as well, but mostly only for the reading part. For the above case, I still use Hibernate, as I've yet to find an efficient way to do it in jOOQ.

Even Lukas Eder, the creator of JOOQ, suggests to use Hibernate for CRUD and JOOQ for querying: https://blog.jooq.org/2015/03/24/jooq-vs-hibernate-when-to-c...

Re: Problems with JPA/Hibernate

#160
post #8

The underlying problem is one of O-R impedance mismatch. Going full SQL and getting rid of the ORM is a possible answer, but it has tradeoffs and is not a silver bullet. It might mean re-creating from scratch an in-house, bug-ridden ORM, or ditching OOP idioms from your language, or both. The author of TFA seems to be going through one of the stages described in "ORM is the Vietnam of Computer Science", an article th…

>“ORM is the Vietnam of Computer Science” In other words it’s a complicated subject with a long and fascinating history, yet Americans will tend to only remember the short, disastrous bit they were directly involved in?

No, the takeaway from Ted Neward, the author of this analogy, is this:

> "Although it may seem trite to say it, Object/Relational Mapping is the Vietnam of Computer Science. It represents a quagmire which starts well, gets more complicated as time passes, and before long entraps its users in a commitment that has no clear demarcation point, no clear win conditions, and no clear exit strategy."

Though I must admit your take is good, too!

Post reply on HN