Seeing the SQL Hibernate runs

Hibernate · lesson 25 of 32 · 3 min read

Make the generated SQL and the query count visible to you before your users find them.

Open this lesson in the learning hub

Key points

  • Turn on the org.hibernate.SQL logger at DEBUG and set format_sql=true. That is the statement as sent.
  • Parameters print as ?. Set org.hibernate.orm.jdbc.bind to TRACE to see the bound values - in development only.
  • The number that matters is statements per request, not their text. Enable hibernate.generate_statistics and read the counts.
  • Better, assert it: a test that fails when a screen goes from 3 queries to 40 catches an N+1 on the day it is introduced.
  • spring.jpa.show-sql=true writes to stdout with no logger control. Fine for a quick look, wrong for a real environment.
  • When a single query is slow, datasource-proxy or p6spy log the statement with its values and its duration, which is what you actually need.

Example

# --- application-dev.properties ----------------------------------
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.orm.jdbc.bind=TRACE
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=true

# --- a test that guards the query count --------------------------
# Statistics stats = entityManagerFactory.unwrap(SessionFactory.class).getStatistics();
# stats.clear();
#
# List<Author> page = authors.findTop20ByCountry("SE");
# page.forEach(a -> a.getBooks().size());
#
# assertThat(stats.getPrepareStatementCount()).isLessThanOrEqualTo(2);
#   without a fetch join this is 21, and the assertion fails in CI
#   instead of in production

Count the statements. The slow page is almost never one slow query.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.