Live data from Hacker News

Problems with JPA/Hibernate

stemlaur.com

41–50 of 195 posts

Re: Problems with JPA/Hibernate

#41
post #6

This article is... Questionable at best. I don't think any of this is an argument against JPA, except that the author doesn't like how it works? I also suspect the author doesn't know hibernate that well. For instance selecting just the fields you need is relatively simple with JPQL: SELECT i.url FROM Image i WHERE i.id = ...

JPA and Hibernate make it very easy to use it incorrectly, its almost like they promote bad SQL queries and ideas. They let users of database connection to write Java-first database queries, when database query should be database first, it's just way too easy to abuse it and get too much data, too many columns and JOINs.

Developers look like JSON looks like, what we send to browser, what formatting it has, validation and size of JSON data, as it's easy to monitor and trim.

Can't say the same about Hibernate. How the hell even hibernate caching works? Why even are there 2 levels of Hibernate cache? It's too easy to create and abuse transactions. Dirty-checking is JUST WAYYYY TOOO EAZY TO ABUSE. not calling, using setter of an instance shouldn't update in database by default omg, It shouldn't be possible for transactions to leak outside some easily specified scope - I've seen one project where transaction leaked to Jackson!! Jackson was calling getters on fields and executing DB queries. JSON ended up as 2.6Mb instead list of 10 fields.

Hibernate is popular because we don't need to learn SQL to get needed data, but it's also super hard to get it right and don't do something stupid by accident.

If in any doubt, refer to JOOQ - it's the SQL-oriented ORM for Java.

Re: Problems with JPA/Hibernate

#42

Earlier quoted context omitted.

Rendering Javascript.

There is https://en.wikipedia.org/wiki/Rhino_(JavaScript_engine) and https://en.wikipedia.org/wiki/GraalVM . The latter of those is the second fastest js server runtime (es4x) according to techempower benchmarks: https://www.techempower.com/benchmarks/#section=data-r20&hw=... I haven't tried any of those, but saying the JVM can't run JS is not true.

GraalVM is not a drop-in replacement for the JVM and Rhino is slow as molasses compared to V8.

Re: Problems with JPA/Hibernate

#43
post #40

I disagree with this bit: A User can be considered unique in one context by its email address, or by its social security number Personally, I'm a fan of giving everything a random UUID, because it's more flexible. It's random and impossible to guess, it scales well because there's no central bottleneck like with an autoincrement, and it's future proof and flexible. What happens when the user changes the email address…

> Personally, I'm a fan of giving everything a random UUID, because it's more flexible Unless of course, you're using a relational database like OP and incur a performance hit from using a UUID as your primary key. Additionally, they're not sortable like autoinc id's. I've always wanted to try out Twitter's Snowflake ID [1] algorithm to get around this, but it requires requires using something like Zookeeper. I've se…

Things like Twitter are special. I'm talking more about a generally sensible way of doing things, which one may need to deviate from in special circumstances.

Why would you want to sort by ID? Sort by something sensible, like the signup date instead. An autoincrement may stop corresponding to time if for instance at some point a database has an external dataset imported into it.

IMO, using an ID for anything other than an opaque identifier is asking for trouble.

Re: Problems with JPA/Hibernate

#44
post #6

This article is... Questionable at best. I don't think any of this is an argument against JPA, except that the author doesn't like how it works? I also suspect the author doesn't know hibernate that well. For instance selecting just the fields you need is relatively simple with JPQL: SELECT i.url FROM Image i WHERE i.id = ...

Giving up basic OO niceties like invariants in your whole domain just to get automatic persistence from some library I agree with the author: it’s insane and no one should accept that tradeoff.

There has to be ways around that though, perhaps using a duplicated domain of DTOs or coercing the ORM to use constructors or private setters to keep encapsulation and invariants.

Re: Problems with JPA/Hibernate

#45
post #13

Earlier quoted context omitted.

TechEmpower Web Framework Benchmarks would like to disagree with you.

I don't think those are particularly realistic workloads, as they don't involve substantial amounts of working with in-memory data. Which of the TechEmpower benchmarks uses an ORM? Before I finished drafting my comment I did have a sentence like this, which I removed, "Barring obscene amounts of optimization", so yes, some web servers like netty and jetty have gotten to a level of good performance in terms of handlin…

JavaScript is hardly cache friendly.

As for Go, that's a language which doubles up the size of every pointer and doesn't even use a moving GC, and last time I looked, the quality of machine code it generated was atrocious. It's not really cache/hardware friendly to do those things. Value types are I suspect being over-estimated here: when Java gets them I am expecting disappointment when they don't magically make everything twice as fast.

Re: Problems with JPA/Hibernate

#46
post #41
post #6

This article is... Questionable at best. I don't think any of this is an argument against JPA, except that the author doesn't like how it works? I also suspect the author doesn't know hibernate that well. For instance selecting just the fields you need is relatively simple with JPQL: SELECT i.url FROM Image i WHERE i.id = ...

JPA and Hibernate make it very easy to use it incorrectly, its almost like they promote bad SQL queries and ideas. They let users of database connection to write Java-first database queries, when database query should be database first, it's just way too easy to abuse it and get too much data, too many columns and JOINs. Developers look like JSON looks like, what we send to browser, what formatting it has, validation…

> How the hell even hibernate caching works? Why even are there 2 levels of Hibernate cache?

https://docs.jboss.org/hibernate/stable/orm/userguide/html_s...

> using setter of an instance shouldn't update in database by default omg

This doesn't happen.. the database won't update until you ask the entity manager to persist the entity.

> I've seen one project where transaction leaked to Jackson!! Jackson was calling getters on fields and executing DB queries. JSON ended up as 2.6Mb instead list of 10 fields.

I suspect you might not agree, but JPA lazy loading is one of the easiest concepts to understand. However, I'd argue that leaking your database models to the view is a mistake to begin with and said application is already incorrect.

> If in any doubt, refer to JOOQ - it's the SQL-oriented ORM for Java.

Both the author/maintainer of jOOq and Hibernate agree that each has their place.

I really am amazed at developers that don't take the time to learn about the tools they use.

Re: Problems with JPA/Hibernate

#47
post #6

This article is... Questionable at best. I don't think any of this is an argument against JPA, except that the author doesn't like how it works? I also suspect the author doesn't know hibernate that well. For instance selecting just the fields you need is relatively simple with JPQL: SELECT i.url FROM Image i WHERE i.id = ...

Giving up basic OO niceties like invariants in your whole domain just to get automatic persistence from some library I agree with the author: it’s insane and no one should accept that tradeoff. There has to be ways around that though, perhaps using a duplicated domain of DTOs or coercing the ORM to use constructors or private setters to keep encapsulation and invariants.

IMO invariants are better handled by a class who's sole responsibility is to enforce and validate said invariants, especially when you have dependencies involved to enforce them (like making sure the Item actually exists in the db).

Value classes like @Entity shouldn't have the responsibility to enforce those business rules.

We can disagree on which way is more object oriented though.

Re: Problems with JPA/Hibernate

#48
post #40

I disagree with this bit: A User can be considered unique in one context by its email address, or by its social security number Personally, I'm a fan of giving everything a random UUID, because it's more flexible. It's random and impossible to guess, it scales well because there's no central bottleneck like with an autoincrement, and it's future proof and flexible. What happens when the user changes the email address…

> Personally, I'm a fan of giving everything a random UUID, because it's more flexible Unless of course, you're using a relational database like OP and incur a performance hit from using a UUID as your primary key. Additionally, they're not sortable like autoinc id's. I've always wanted to try out Twitter's Snowflake ID [1] algorithm to get around this, but it requires requires using something like Zookeeper. I've se…

There's no need for zookeeper or any centralised/decentralised service. In the article you link they mention why depending on something like zookeeper is suboptimal. Given that you have less than something like 2048 web server instances, (don't remember how many bits they give to worker_number and the snowflake github repo is basically unavaible) all you need to do is make sure every instance has a rank/worker_number (infrastructure/devops problem) which the instance will use when it generates the snowflake ids. Sidenote snowflake also suffers from the unix epoch 2038 problem, but that can be simply solved by adding bits for epoch number.

Re: Problems with JPA/Hibernate

#49

Earlier quoted context omitted.

I don't think those are particularly realistic workloads, as they don't involve substantial amounts of working with in-memory data. Which of the TechEmpower benchmarks uses an ORM? Before I finished drafting my comment I did have a sentence like this, which I removed, "Barring obscene amounts of optimization", so yes, some web servers like netty and jetty have gotten to a level of good performance in terms of handlin…

> Which of the TechEmpower benchmarks uses an ORM? There are two: single query and multiple query.

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 of the kind of code you would write? I think that the TechEmpower benchmarks suffer from many of the same problems the language benchmarks game benchmarks do - micro-optimization, unrealistic workloads.

My experience tells me that you an get any sufficient level of performance in almost any language, but that you are going to pay for some languages more in opex than others, particularly in memory usage. It takes more compute spend for a workload written in Java than one written in Go, all other things being equal. That's not to say Java is a bad language, but it does lack many features - some of them being intentional design decisions - which make it less cost effective to operate systems built on Java. However, we know that a significant cost is the cost to develop, so it's hard for me to say Java is a bad language for that reason either.

And memory usage is generally a good predictor of density in terms of scheduling workloads, be it Tomcat servers (back in the day) or VMs or containers these days. I also think that Java suffers, performance wise, from boxing values and pointer chasing / poor cache locality. The default container implementations are just, well, it would be polite to simply say that they're as good as the language allows.

However, data is better than claimed experience, no?

I just opened up the raw benchmark stats[1] for the database updates route. It's one that my favorite languages don't do well in, but I was curious about the operational overhead of running them in memory usage, something I've mentioned quite a lot up above.

I looked at a vertx-postgresql benchmark for the "updates" TechEmpower. This is a high performing implementation without an ORM[2]

I also looked at quarkus + reactive routes + hibernate, which appears to use hibernate, applicable to the original post[3].

And lastly, I looked at actix diesel, another ORM using implementation[4].

    java quarkus-hibernate:  3.9GiB memory (peak, start of test)
    java quarkus-hibernate:  3.1GiB memory (lowest value, near end of test)
    java vertx-postgres:     2.35GiB memory (consistent)

    rust actix-diesel:       1.2GiB memory
Standard deviation was:

    java quarkus-hibernate:  221.4MiB
    java vertx-postgres:       1.9MiB
    rust actix-diesel:         0.5MiB
I included the steady state for quarkus because its memory usage (perhaps due to a config flag starting it with a 4GiB heap?) started out extremely high and decreased over the course of the run. That likely affects the standard deviation, which I included to highlight that I didn't try to cherry-pick results.

Perhaps the funniest thing to me digging into it is, again due to the absurdity of Java's design decisions, to make sure that "Integer" objects are efficient, the Java benchmarks use the command line parameter "-Djava.lang.Integer.IntegerCache.high=10000". This tells you that if the benchmark used a wider range of random values[5], performance would degrade. Have you ever heard of a language requiring an integer cache? It's absurd to me that Java, rather than implement value types, requires Integers to be interned for performance.

Are there any other languages in the TechEmpower benchmark or the Debian benchmark game (formerly went by another name) that requires setting an "IntegerCache" to optimize... allocating integers? I mean, come on. You can't tell me this is a language that was designed for performance when integers can't be directly stored in arrays and instead have to be autoboxed and a cache is needed to intern them!

I will say one final thing: cost to operate/memory efficiency is just one metric for measuring languages. I think that Java is actually a pretty bad language for a lot of reasons, but path dependence has produced an extremely rich ecosystem that gives developers a lot of flexibility and a lot of tools to use when writing it. I think Kotlin, Scala, and even Clojure are by far more pleasurable languages to write in, though the JVM still holds them back for all the reasons above.

[1] Raw results from https://tfb-status.techempower.com/unzip/results.2021-01-13-...

[2] You can see they have simply hardcoded the SQL. See: https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...

[3] https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...

[4] https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...

[5] The update benchmark only requires random numbers between 1 and 10,000. Performance of Java apps would degrade if they were asked to use boxed integers greater than 10,000, which is possibly the most absurd statement I have said of any programming language ever. See: https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Proj...

Re: Problems with JPA/Hibernate

#50
post #46
post #41

Earlier quoted context omitted.

JPA and Hibernate make it very easy to use it incorrectly, its almost like they promote bad SQL queries and ideas. They let users of database connection to write Java-first database queries, when database query should be database first, it's just way too easy to abuse it and get too much data, too many columns and JOINs. Developers look like JSON looks like, what we send to browser, what formatting it has, validation…

> How the hell even hibernate caching works? Why even are there 2 levels of Hibernate cache? https://docs.jboss.org/hibernate/stable/orm/userguide/html_s... > using setter of an instance shouldn't update in database by default omg This doesn't happen.. the database won't update until you ask the entity manager to persist the entity. > I've seen one project where transaction leaked to Jackson!! Jackson was calling get…

> 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?

Post reply on HN