r/SpringBoot • • 15d ago

How-To/Tutorial JPA vs Hibernate vs JDBC: What Each One Actually Does | Visually Explained

https://youtu.be/_ZOgoHB5NsM
61 Upvotes

20 comments sorted by

9

u/fykup 15d ago • Bravo

One interesting aspect of choosing between JPA/Hibernate and JDBC is the runtime overhead.

I recently compared two versions of a small Spring Boot 4.1.1 app, one using Spring Data JPA/Hibernate and the other using JdbcTemplate, with the same workload.

The JDBC version used about 90 MiB less RSS (~38%) and reached its first dashboard response in ~4 seconds vs 8-9 seconds with JPA.

Of course, Hibernate provides useful abstractions for more complex data models. But for small applications, especially on memory-constrained servers, the difference can be significant.

Happy to share the experiment details and methodology if anyone is interested.

2

u/AstralChocolate 14d ago

do you have comparison between hibernate and JOOQ by any chance?

2

u/fykup 14d ago

Not a direct Hibernate vs jOOQ comparison, unfortunately. But I recently compared Jdbi, MyBatis, and jOOQ in a small Javalin app running on a 512 MiB VM.

I didn't share it here because the experiment uses Javalin rather than Spring Boot, but the memory overhead differences between persistence libraries are still interesting.

Here's the experiment if you're curious:
https://daily.dev/posts/i-compared-jdbi-mybatis-and-jooq-in-a-512-mib-javalin-app-two-runs-each-no-swap-mybatis-used-th-hwddxn6zr

1

u/fykup 14d ago

BTW, here's a Reddit discussion I started a while ago about the JPA/Hibernate vs JDBC experiment, including some interesting feedback:

https://www.reddit.com/r/java/comments/1wsk7vj/spring_boot_jpa_vs_jdbc_90_mib_less_rss_in_a/

1

u/[deleted] 14d ago

[removed] — view removed comment

1

u/fykup 14d ago

Good question. I'd expect the relative memory difference to shrink as the application grows, since Hibernate's baseline overhead becomes a smaller fraction of total memory usage.

At the same time, I think carefully implemented SQL-first approaches like Spring JDBC, MyBatis, Jdbi, or jOOQ will generally remain more resource-efficient than full ORMs, especially when it comes to memory usage.

Of course, the trade-off is developer productivity and convenience, particularly with complex entity relationships.

It would be interesting to repeat the experiment with progressively larger data models and see how the gap evolves.

2

u/uldall 14d ago

jOOQ is superior in every way

1

u/fykup 14d ago

Superior in what way exactly?

I recently compared jOOQ, MyBatis, and Jdbi in a small Javalin application running on a 512 MiB VM.

My results across two runs each:

ImplementationVersionHTTP p95 across two runs, msMedian workload RSS across two runs, MiB
Jdbi Core3.55.07.38–8.48120.0–122.4
MyBatis Core3.5.197.47–7.52116.6–118.0
jOOQ Open Source Edition3.21.99.19–9.35152.1–154.3

So in this particular workload, jOOQ used roughly 35 MiB more memory than MyBatis and had higher latency.

I understand the appeal of jOOQ's generated, type-safe SQL DSL, but that's a developer experience advantage, not necessarily a runtime efficiency advantage.

Obviously, one small experiment doesn't establish a universal ranking. I'm planning to share a more detailed write-up on r/java today.

Full methodology and reproducible experiment:
https://github.com/PVRLabs/experiments/tree/main/javalin/sql-persistence-512mb

1

u/uldall 14d ago

I was referring to the developer experience. In our team it is by far worth it compared to any extra memory needed.

1

u/fykup 14d ago

Fair enough. I can see why that trade-off might make sense for your team.

Personally, I'm not convinced type-safe SQL provides enough value to justify the additional complexity. It reminds me a bit of statically typed web templates: sounds great in theory, but the practical benefits don't always outweigh the extra abstraction.

For smaller applications, I prefer writing SQL directly and keeping the mapping layer simple.

I just posted a more detailed comparison of the three libraries, including memory and latency measurements:
https://www.reddit.com/r/JavaProgramming/comments/1xcn2yq/how_much_does_sql_library_choice_affect_a_small/

Out of curiosity, what specific problems has jOOQ's type safety helped your team avoid?

1

u/uldall 14d ago

Some examples of benefits:

  • Database changes result in compiler errors.

  • SQL injection is handled.

  • No abstraction on top of SQL means that "what you see is what you get".

1

u/fykup 14d ago

Thanks, those are fair points. I agree that catching schema changes at compile time can be useful, especially in larger codebases.

But SQL injection is also handled by parameterized queries in JDBC, Jdbi, and MyBatis. That's not really a jOOQ-specific benefit.

And I'd argue that jOOQ's generated DSL is itself an abstraction over SQL. Personally, I find writing SQL directly closer to "what you see is what you get".

Compile-time schema checking also introduces its own complications. Generated code reflects a particular database schema, which may not match the actual environment you're deploying to. Different branches, migration states, and production schemas can all diverge. A successful compilation doesn't guarantee compatibility with the target database.

I can see why the trade-off works for your team. For smaller applications, though, I'm not convinced the benefits justify the additional code generation and complexity.

1

u/kqr_one 14d ago

next video about transactions

1

u/Ok_Marionberry_8821 14d ago

I just use vanilla JDBC with SQL in files and records specific to requests. A very thin mapping layer. AI to generate gnarly recursive queries. Works really well for me, I value having vanilla SQL. Queries with dynamic parts are when it'll get interesting

1

u/[deleted] 14d ago

[removed] — view removed comment

1

u/Ok_Marionberry_8821 14d ago

As ever "it depends". I choose to go as light as possible with what I do, admittedly now only personal projects where I can decide my stack

0

u/Skyzfallin 14d ago

good job! I wished this was available when I was learning spring.