How to Understand What Hibernate Does Under the Hood: Hibernate Statistics vs Classic Logs
When we enable show-sql, we see queries in the console. But after a single endpoint call, you might see 50+ SQL queries, and it's unclear where they came from.
Classic approach:
select * from orders where customer_id = 1 select * from order_items where order_id = 1 select * from order_items where order_id = 2 ...
Sound familiar? You see what happened, but not how many entities were loaded or how long each operation took.
The Problem with Classic Logging
You get individual queries, but you lose the big picture:
• How many times was the same entity loaded? • What was the second-level cache hit ratio? • Which query took the most time? • How many inserts, updates, or deletes happened?
Hibernate Statistics: The Big Picture
Hibernate provides a Statistics API. When we enable it, we get aggregated data:
var statistics = sessionFactory.getStatistics(); statistics.setStatisticsEnabled(true);
var methodStat = new MethodStatistics(); methodStat.addLoadCount(statistics.getEntityLoadCount()); methodStat.addInsertCount(statistics.getEntityInsertCount()); methodStat.addUpdateCount(statistics.getEntityUpdateCount()); methodStat.addDeleteCount(statistics.getEntityDeleteCount()); methodStat.addSecondLevelCacheHitCount(statistics.getSecondLevelCacheHitCount()); methodStat.addSecondLevelCacheMissCount(statistics.getSecondLevelCacheMissCount());
What you get:
jpa statistic at OrderService#createOrder: { "statisticByEntity": { "Order": {"loadCount": 1, "insertCount": 1}, "OrderItem": {"loadCount": 3} }, "statisticByCache": { "Order": {"hit_count": 0, "miss_count": 1, "put_count": 1} } }
The key metrics we track:
| Metric | Why It Matters | | ------------------------- | -------------------------- | | EntityLoadCount | Shows N+1 problems | | SecondLevelCacheHitCount | Cache efficiency | | SecondLevelCacheMissCount | Cache tuning needed | | Insert/Update/DeleteCount | Batch operation efficiency |
How We Use It
We enable statistics in development. We log slow queries and track entity load counts. If an entity is loaded 50 times for a single operation, that's a clear N+1 indicator.
We also set up alerts. If cache hit ratio drops below 50%, the team gets notified. This helps us find problems before users report them.
Result:
Instead of reading hundreds of SQL lines, we see a clear summary:
• Which entities were loaded • How many times • Cache performance • Query execution count
This makes performance analysis faster and helps teams understand the real cost of their data access patterns.
───