Live data from Hacker News

Problems with JPA/Hibernate

stemlaur.com

61–70 of 195 posts

Re: Problems with JPA/Hibernate

#61
post #53

Earlier quoted context omitted.

> This doesn't happen.. the database won't update until you ask the entity manager to persist the entity. Doesn't this happen through automatic dirty checking?

No calling a setter on an Entity doesn't automatically issue an sql UPDATE query. You need to ask the EntityManager to merge or persist the entity and it's changes. Obviously JPA knows what fields were updated via dirty checking.. that's almost half the point of an ORM.

I'm not talking about "dirty checking". I'm talking about "automatic dirty checking". Take for example this code I got from this article[1]:

    SessionFactory  sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Person person  = session.load(Person.class, 2); //loads Person object for id 2
    person.setAge(32);
    tx.commit();
    session.close();
    HibernateUtil.closeSessionFactory();
It results in an updated age for the person in the DB. However, EntityManager was never directly notified about the change in the person object.

[1] - https://learnjava.co.in/automatic-dirty-checking-in-hibernat...

Re: Problems with JPA/Hibernate

#62
post #53

Earlier quoted context omitted.

> This doesn't happen.. the database won't update until you ask the entity manager to persist the entity. Doesn't this happen through automatic dirty checking?

No calling a setter on an Entity doesn't automatically issue an sql UPDATE query. You need to ask the EntityManager to merge or persist the entity and it's changes. Obviously JPA knows what fields were updated via dirty checking.. that's almost half the point of an ORM.

[deleted]

Re: Problems with JPA/Hibernate

#63
post #53

Earlier quoted context omitted.

No calling a setter on an Entity doesn't automatically issue an sql UPDATE query. You need to ask the EntityManager to merge or persist the entity and it's changes. Obviously JPA knows what fields were updated via dirty checking.. that's almost half the point of an ORM.

I'm not talking about "dirty checking". I'm talking about "automatic dirty checking". Take for example this code I got from this article[1]: SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person person = session.load(Person.class, 2); //loads Person object for id 2 person.setAge(32); tx.commit(); session.c…

That's because JPA isn't involved here. It's directly using hibernate api's and not sticking to the standard which is what I was talking about.

Re: Problems with JPA/Hibernate

#64

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…

Exactly! And can you even call yourself an experienced Java developer if you haven't written your own ORM at some point?

Re: Problems with JPA/Hibernate

#65

Earlier quoted context omitted.

Sorry, I should have been more precise. I am very, very familiar with the TechEmpower benchmarks and I first learned Java around SE 5, right after they switched from 1.x numbering. Please don't mistake me for someone who just learned about Go or Rust and is evangelizing them because I think they're the cool new thing. Which of the Java implementations for the TechEmpower benchmarks use an ORM? Are they representative…

> I think that the TechEmpower benchmarks suffer from many of the same problems the language benchmarks game benchmarks do - micro-optimization, unrealistic workloads. ... It takes more compute spend for a workload written in Java than one written in Go, all other things being equal. Well which is it, then? You say Java is slower, the benchmarks say otherwise. What other benchmark would you accept? I hate autoboxing…

I think that if all you're doing is serving the results of plain SQL queries, which is what the TechEmpower benchmarks are, then it's really hard to pick a bad language. Almost every language is capable of tens of thousands of requests per second. Even Ruby, a language we haven't brought up and is dreadfully slow, will do thousands of requests per second with Rails. Beautiful language, abysmal performance (relative to what's possible).

Once you're doing non-trivial things on Java, and I've outlined what those things are in my previous comments and they primarily revolve around memory, wall clock CPU time correspondingly increases as your program spends more time chasing pointers on the heap, poor cache locality, lack of value types, poor monomorphization of generics (until the JIT kicks in), and so on. These things all add up.

I'm not saying it's impossible for Java to be fast, after all, if you just store everything in a "private final double[]" like most of the Benchmarks Game implementations do, sure, the JIT will do wonders for you. But that isn't real world Java, is it?

Real-world Java web servers do more than just respond to epoll_wait(2) events on a loop by sending some bytes to a database, getting them back, and sending them straight back to the client. There's usually more serialization, more authentication, more logging, more metric exporting, more middleware doing one thing or another.

One last thing: GraalVM is the most exciting thing to happen to Java performance since NIO and the newer garbage collectors aiming for sub-ms stop the world times. Quarkus, which I googled over the course of writing my comments, is by far the most interesting new tool I saw for shipping Java in production efficiently by building on GraalVM to deliver web servers in megabytes, not gigabytes of resident memory: https://quarkus.io/

It's a shame Quarkus in the benchmark I saw used so much more memory. It looks like it should be possible to fix that.

Re: Problems with JPA/Hibernate

#67

In my extensive experience managing teams using JPA ORMs including Hibernate and EclipseLink, you not only get to learn the unavoidable details of your target database’s SQL, but also the complex, non-obvious side effects - especially caching interactions and performance edge cases - of the ORM as well. You also get to learn two distinct but similar query languages (one of which you can’t use anywhere else but Java).…

I am called apon to investigate database performance problems. Teams using Hibernate sometimes send me the Hibernate query. This is not enough to understand the SQL which has been issued. I would also need to see all the entity objects, and maybe some configuration parameters. Without the SQL, which nobody can exactly predict, it is difficult to performance tune.

So they turn on logging, get the SQL, and email that unreadable mess. In most of the cases I have seen, the SQL is fetching much more from the database than what the code really needs.

The first step when optimising SQL is to only ask for data that you actually need. Hibernate, as I have seen it used, defaults to fetching too many columns. I cut the SQL down, and come up with a performant statement. The developer has the challenge of translating the performant SQL back into Hibernate.

Hibernate makes easy things easier and harder things harder.

Re: Problems with JPA/Hibernate

#68

Earlier quoted context omitted.

Actually mixing raw queries with JPQL/Hibernate queries is the worst of all worlds. To get it right, you will end up making explicit calls to let the EntityManager know what you want each side to be doing to play nice.

I've never hit such a bug. Can you expand on what (and when) added complexity would a raw query have versus a raw query without hibernate?

It's not a bug, it's by design.

Re: Problems with JPA/Hibernate

#69

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…

Gosh has it been 15 years already? I never liked Java much. But several companies I liked and hired me where using mostly that. Then I did some consulting / freelancing / firefighting. ORM and mostly Hibernate was often a topic.

My experience and methodology is as follow :

- Write test for your ORM layer. Possibly not in Java. Some high level integration type test. ( calling your web-layer or API and checking for what comes out )

- Burn your ORM layer down.

- Have someone who know the business logic sit with you. And re-write the ORM layer from mostly scratch.

- While doing the above, train that person on the very redondant gotcha ( Inverse n to n, accidental carthesian product, bad ID generation, compulsive flush, un-needed @lazy or @eager to deal with performance, @embedded abuse and fucked up SQL schema because of the previous)

- Train all dev on the persistence lifecycle of stuff in JPA. "No, most likely you won't have to call .persist or .merge yourself" being the bottomline

- Have a shiny documented exemple of 1 to 1, N to 1, N to N examples ( both with or without inverse link )

- If some report or API needs a fucked up SQL query with 18 join. Write that thing in native SQL and shove it in your DAO. You don't need to mess up you'r whole DAO layer for those 3 queries

- Pray

- Run the test from step 1.

--- TL;DR : if the ORM layer is somewhat clean. you can mostly forget about it. On the project I'm on now, I did not had to touch it more than once in 2 years. ( and that was terrible, granted, we touched a test and stuff that had nothing to do with it started to blow up. But still, once in 2 years is not a lot )

Re: Problems with JPA/Hibernate

#70
post #9

From my experience ORMs are good time savers when you have relatively simple query needs, but fall down when things get really complex.

"Really complex" means getting down to 6 or 7 joins for your typical SQLAlchemy or Django ORM query. These sorts of queries comprise 5% of my queries, tops. Seems like a fair tradeoff.

Exactly, with hibernate if something is too hairy, I use the native query system. ( and hibernate still map the result for me )
Post reply on HN