Integrating with Hibernate

Hibernate is an Object/Relational Mapping (ORM) solution for Java environments. It uses JBoss Logging as its logging API. If you have a working Log4j installation, JBoss Logging requires no extra installation steps on your part, since it is shipped with an integrated bridge to Log4j API – see Supported Log Managers by JBoss Logging for more information.

Struggling with the logging API, implementation, and bridge concepts? Click for an introduction.
Logging API

A logging API is an interface your code or your dependencies directly logs against. It is required at compile-time. It is implementation agnostic to ensure that your application can write logs, but is not tied to a specific logging implementation. Log4j API, SLF4J, JUL (Java Logging), JCL (Apache Commons Logging), JPL (Java Platform Logging) and JBoss Logging are major logging APIs.

Logging implementation

A logging implementation is only required at runtime and can be changed without the need to recompile your software. Log4j Core, JUL (Java Logging), Logback are the most well-known logging implementations.

Logging bridge

Logging implementations accept input from a single logging API of their preference; Log4j Core from Log4j API, Logback from SLF4J, etc. A logging bridge is a simple logging implementation of a logging API that forwards all messages to a foreign logging API. Logging bridges allow a logging implementation to accept input from other logging APIs that are not their primary logging API. For instance, log4j-slf4j2-impl bridges SLF4J calls to Log4 API and effectively enables Log4j Core to accept input from SLF4J.

To make things a little bit more tangible, consider the following visualization of a typical Log4j Core installation with bridges for an application:

Visualization of a typical Log4j Core installation with SLF4J, JUL, and JPL bridges
@startuml

frame "Compile time" {
  [Application] --> [Log4j API] : logs to

  [Log4j API] #Cyan

  [SLF4J] #Cyan

  [Library 1] --> [SLF4J] : logs to
  [Application] --> [Library 1] : uses
  [Application] --> [Library 2] : uses
  [Application] --> [Library 3] : uses
}

frame Runtime {

  [Log4j Core] <.. [Log4j API] : is implemented by
  [Log4j Core] <.. (log4j2.xml) : is provided to
  [Log4j Core] #LightGreen

  [JPL-to-Log4j] ..> [Log4j Core] : forwards to
  [JPL-to-Log4j] #Yellow

  [SLF4J-to-Log4j] ..> [Log4j Core] : forwards to
  [SLF4J-to-Log4j] #Yellow

  [JUL-to-Log4j] ..> [Log4j Core] : forwards to
  [JUL-to-Log4j] #Yellow

  frame JRE {
    [JPL] #Cyan
    [JUL] #Cyan
  }

}

[Library 2] --> [JUL] : logs to
[Library 3] --> [JPL] : logs to

[JPL] ..> [JPL-to-Log4j] : is implemented by
[JUL] ..> [JUL-to-Log4j] : is implemented by
[SLF4J] ..> [SLF4J-to-Log4j] : is implemented by

legend top right
  | <#LightGreen> | Logging implementation |
  | <#Yellow> | Logging bridge |
  | <#Cyan> | Logging API |
  | <size:18><U+2192></size> | Compile-time usage |
  | <size:18><U+21E2></size> | Runtime usage |
endlegend

@enduml

Configuration

After successfully wiring Hibernate – to be precise, JBoss Logging – to log using Log4j API, you can fine-tune the verbosity of Hibernate loggers in your Log4j Core installation to accommodate your needs:

  • XML

  • JSON

  • YAML

  • Properties

Snippet from an example log4j2.xml configuring Hibernate-specific loggers
<Loggers>

  <!-- Log just the SQL -->
  <Logger name="org.hibernate.SQL" level="DEBUG"/>

  <!-- Log JDBC bind parameters and extracted values

       Warning! (1)
       JDBC bind parameters can contain sensitive data!
       Passwords, credit card numbers, etc.
       Use these logger configurations with care! -->
  <!--
  <Logger name="org.hibernate.type" level="TRACE"/>
  <Logger name="org.hibernate.orm.jdbc.bind" level="TRACE"/>
  <Logger name="org.hibernate.orm.jdbc.extract" level="TRACE"/>
  -->
Snippet from an example log4j2.json configuring Hibernate-specific loggers
"Loggers": {
  "Logger": [

    // Log just the SQL
    {
      "name": "org.hibernate.SQL",
      "level": "DEBUG"
    }

    // Log JDBC bind parameters and extracted values
    //
    // Warning! (1)
    // JDBC bind parameters can contain sensitive data:
    // Passwords, credit card numbers, etc.
    // Use these logger configurations with care!
    //{
    //  "name": "org.hibernate.type",
    //  "level": "TRACE"
    //},
    //{
    //  "name": "org.hibernate.orm.jdbc.bind",
    //  "level": "TRACE"
    //},
    //{
    //  "name": "org.hibernate.orm.jdbc.extract",
    //  "level": "TRACE"
    //}
Snippet from an example log4j2.yaml configuring Hibernate-specific loggers
Loggers:

  Logger:

    #  Log just the SQL
    - name: "org.hibernate.SQL"
      level: "DEBUG"

    # Log JDBC bind parameters and extracted values
    #
    # Warning! (1)
    # JDBC bind parameters can contain sensitive data!
    # Passwords, credit card numbers, etc.
    # Use these logger configurations with care!
    #- name: "org.hibernate.type"
    #  level: "TRACE"
    #- name: "org.hibernate.orm.jdbc.bind"
    #  level: "TRACE"
    #- name: "org.hibernate.orm.jdbc.extract"
    #  level: "TRACE"
Snippet from an example log4j2.properties configuring Hibernate-specific loggers
# Log just the SQL
logger.0.name = org.hibernate.SQL
logger.0.level = DEBUG

# Log JDBC bind parameters and extracted values
#
# Warning! (1)
# JDBC bind parameters can contain sensitive data!
# Passwords, credit card numbers, etc.
# Use these logger configurations with great care!
#logger.1.name = org.hibernate.type
#logger.1.level = TRACE
#logger.2.name = org.hibernate.orm.jdbc.bind
#logger.2.level = TRACE
#logger.3.name = org.hibernate.orm.jdbc.bind
#logger.3.level = TRACE
1 Due to the sensitivity of the data involved, you are strongly advised to use these logger configurations only in development environments.

We strongly advise you to avoid using the hibernate.show_sql property! (It maps to spring.jpa.show-sql in Spring Boot.) hibernate.show_sql writes to the standard error output stream, not to the logging API. Logger-based configuration exemplified above gives a finer-grained control over logging and integrates with the logging system. Combining hibernate.show_sql with logger-based configuration duplicates the logging effort.