All stories
Java

Hibernate Was Slowing Us Down. Here's What We Did About It.

H
hemant-kumar

May 15, 2026

We had N+1 queries everywhere and didn't know it until production fell over on a Tuesday afternoon. The database was hammered, response times went from 80ms to 4 seconds, and the culprit was Hibernate doing exactly what we told it to do — lazily loading associations one by one for every row in a result set.

How we got there

The codebase had the classic pattern: a @OneToMany relationship with FetchType.LAZY, a list page that loaded 50 items, and a template that called item.getComments().size() for each one. That's 51 queries instead of 1. We'd never noticed in dev because dev had 10 rows of test data. Production had 50,000.

The fix everyone suggests first is switching to FetchType.EAGER. Don't. You'll trade N+1 for loading entire object graphs when you just needed a count. I made that mistake and it was worse.

What actually fixed it

We used @EntityGraph on the specific queries that needed the association, and left the default as LAZY everywhere else. Like this:

@EntityGraph(attributePaths = {"comments"})
@Query("SELECT p FROM Post p WHERE p.published = true")
List<Post> findPublishedWithComments();

For the list pages where we only needed counts, we moved to a @Query with a COUNT subquery instead of loading the collection at all. Dropped those 51 queries to 2.

We also turned on Hibernate's SQL logging in staging permanently — spring.jpa.show-sql=true with format_sql=true. Painful to read but essential. If a page is firing more than 5 queries, something is wrong.

When to drop Hibernate entirely

For reporting queries — anything with GROUP BY, complex joins across 4+ tables, or aggregations — we stopped using Hibernate and dropped to JDBC directly with JdbcTemplate. Hibernate's HQL can express most of this but the generated SQL is often terrible and impossible to tune. Raw SQL is readable, predictable, and debuggable.

The lesson isn't that Hibernate is bad. It's that ORMs are good at CRUD and bad at analytics, and using one tool for both is the actual mistake.

Java

0

If you found this helpful, give it some claps!

SHARE THIS ARTICLE

Share on X
LinkedIn

Responses0

Sign in to join the conversation

Sign in