Hibernate Logging with Log4j2 Using Properties File

This tutorial will guide you through setting up and configuring Hibernate logging with Log4j2 using a properties file. We'll create a simple application that logs Hibernate operations to demonstrate the logging configuration.

Introduction

Logging is an essential part of any application, helping developers to debug and monitor application behavior. Hibernate integrates well with various logging frameworks, including Log4j2. By configuring Log4j2, you can control the logging level and output format of Hibernate logs.

In this tutorial, we will:

  1. Set up a Maven project with Hibernate and Log4j2 dependencies.
  2. Configure Hibernate.
  3. Create a Log4j2 properties file.
  4. Create entity classes (Product).
  5. Demonstrate Hibernate logging with a sample application.

Step 1: Set Up Your Project

1.1 Create a Maven Project

Open your IDE and create a new Maven project.

1.2 Add Dependencies

Update your pom.xml file to include the necessary dependencies for Hibernate and Log4j2.

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>hibernate-log4j2-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- Hibernate ORM -->
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.4.0.Final</version>
        </dependency>

        <!-- H2 Database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>

        <!-- Log4j2 Core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1</version>
        </dependency>

        <!-- Log4j2 API -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.1</version>
        </dependency>

        <!-- Log4j2 SLF4J Binding -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.17.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.3 Configure Hibernate

Create a file named hibernate.cfg.xml in the src/main/resources directory to configure Hibernate. This file contains the database connection settings and Hibernate properties.

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
    </session-factory>
</hibernate-configuration>

Explanation:

  • hibernate.dialect specifies the SQL dialect to be used.
  • hibernate.connection.driver_class specifies the JDBC driver class.
  • hibernate.connection.url specifies the JDBC URL for the database connection.
  • hibernate.connection.username and hibernate.connection.password specify the database credentials.
  • hibernate.hbm2ddl.auto specifies the schema generation strategy.
  • hibernate.show_sql specifies whether to show SQL statements in the logs.
  • hibernate.format_sql specifies whether to format the SQL statements.

Step 2: Configure Log4j2

2.1 Create a Log4j2 Properties File

Create a file named log4j2.properties in the src/main/resources directory to configure Log4j2.

status = error
name = PropertiesConfig

# Console appender
appender.console.type = Console
appender.console.name = ConsoleAppender
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# File appender
appender.file.type = File
appender.file.name = FileAppender
appender.file.fileName = logs/hibernate.log
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Root logger
rootLogger.level = info
rootLogger.appenderRefs = console, file
rootLogger.appenderRef.console.ref = ConsoleAppender
rootLogger.appenderRef.file.ref = FileAppender

# Hibernate logger
logger.hibernate.name = org.hibernate
logger.hibernate.level = debug
logger.hibernate.additivity = false
logger.hibernate.appenderRefs = console, file
logger.hibernate.appenderRef.console.ref = ConsoleAppender
logger.hibernate.appenderRef.file.ref = FileAppender

Explanation:

  • The appender.console section configures a console appender that writes logs to the console.
  • The appender.file section configures a file appender that writes logs to a file named hibernate.log in the logs directory.
  • The rootLogger section configures the root logger with an info level and attaches both the console and file appenders.
  • The logger.hibernate section configures a logger for Hibernate with a debug level and attaches both the console and file appenders.

Step 3: Create Entity Class

3.1 Create the Product Entity Class

Create an entity class Product that will be mapped to a table in the database.

package com.example.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    // Getters and setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Explanation:

  • The @Entity annotation specifies that the class is an entity and is mapped to a database table.
  • The @Id annotation specifies the primary key of the entity.
  • The @GeneratedValue(strategy = GenerationType.IDENTITY) annotation specifies that the primary key is auto-incremented.

Step 4: Demonstrate Hibernate Logging

Create a MainApp class to demonstrate Hibernate logging functionality. This class performs CRUD operations on the Product entity and logs the operations.

package com.example.main;

import com.example.entity.Product;
import com.example.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class MainApp {
    public static void main(String[] args) {
        // Create product
        Product product = new Product();
        product.setName("Laptop");
        product.setPrice(1500.00);

        // Save product
        saveProduct(product);

        // Retrieve and update product
        Product retrievedProduct = getProduct(product.getId());
        if (retrievedProduct != null) {
            retrievedProduct.setPrice(1400.00);
            updateProduct(retrievedProduct);
        }

        // Delete product
        deleteProduct(retrievedProduct.getId());

        // Shut down Hibernate
        HibernateUtil.shutdown();
    }

    public static void saveProduct(Product product) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;

        try {
            transaction = session.beginTransaction();
            session.save(product);
            transaction.commit();
            System.out.println("Product saved successfully");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    public static



 Product getProduct(Long id) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Product product = null;

        try {
            product = session.get(Product.class, id);
            if (product != null) {
                System.out.println("Product retrieved: " + product.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }

        return product;
    }

    public static void updateProduct(Product product) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;

        try {
            transaction = session.beginTransaction();
            session.update(product);
            transaction.commit();
            System.out.println("Product updated successfully");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    public static void deleteProduct(Long id) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;

        try {
            transaction = session.beginTransaction();
            Product product = session.get(Product.class, id);
            if (product != null) {
                session.delete(product);
                transaction.commit();
                System.out.println("Product deleted successfully");
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

Explanation:

  1. Create Product:

    Product product = new Product();
    product.setName("Laptop");
    product.setPrice(1500.00);
    

    A Product entity is created and its properties are set.

  2. Save Product:

    saveProduct(product);
    

    The saveProduct method is called to save the Product entity.

  3. Retrieve and Update Product:

    Product retrievedProduct = getProduct(product.getId());
    if (retrievedProduct != null) {
        retrievedProduct.setPrice(1400.00);
        updateProduct(retrievedProduct);
    }
    

    The getProduct method is called to retrieve the Product entity by its ID. If the product is found, its price is updated and the updateProduct method is called to save the changes.

  4. Delete Product:

    deleteProduct(retrievedProduct.getId());
    

    The deleteProduct method is called to delete the Product entity by its ID.

  5. Shut Down Hibernate:

    HibernateUtil.shutdown();
    

    The shutdown method is called to close the SessionFactory and release resources.

Sample Output

When you run the MainApp class, you should see logs in the console and in the logs/hibernate.log file. The logs will include Hibernate operations such as saving, updating, and deleting the product.

Example console output:

2023-05-24 12:00:00 INFO  c.e.m.MainApp:29 - Product saved successfully
2023-05-24 12:00:01 INFO  c.e.m.MainApp:46 - Product retrieved: Laptop
2023-05-24 12:00:02 INFO  c.e.m.MainApp:64 - Product updated successfully
2023-05-24 12:00:03 INFO  c.e.m.MainApp:81 - Product deleted successfully

Example log file output (logs/hibernate.log):

2023-05-24 12:00:00 INFO  org.hibernate.Version:33 - HHH000412: Hibernate Core {6.4.0.Final}
2023-05-24 12:00:00 INFO  org.hibernate.cfg.Environment:259 - HHH000206: hibernate.properties not found
2023-05-24 12:00:00 INFO  org.hibernate.annotations.common.reflection.java.JavaReflectionManager:36 - HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2023-05-24 12:00:01 DEBUG org.hibernate.SQL:149 - insert into Product (description, name, price, id) values (?, ?, ?, ?)
2023-05-24 12:00:01 INFO  c.e.m.MainApp:29 - Product saved successfully
2023-05-24 12:00:01 DEBUG org.hibernate.SQL:149 - select product0_.id as id1_0_0_, product0_.description as descript2_0_0_, product0_.name as name3_0_0_, product0_.price as price4_0_0_ from Product product0_ where product0_.id=?
2023-05-24 12:00:01 INFO  c.e.m.MainApp:46 - Product retrieved: Laptop
2023-05-24 12:00:02 DEBUG org.hibernate.SQL:149 - update Product set description=?, name=?, price=? where id=?
2023-05-24 12:00:02 INFO  c.e.m.MainApp:64 - Product updated successfully
2023-05-24 12:00:03 DEBUG org.hibernate.SQL:149 - delete from Product where id=?
2023-05-24 12:00:03 INFO  c.e.m.MainApp:81 - Product deleted successfully

Conclusion

In this tutorial, we have successfully demonstrated how to configure Hibernate logging with Log4j2 using a properties file. We set up a Hibernate project, configured Hibernate and Log4j2, created an entity class, and demonstrated logging functionality with a sample application. This guide provides a solid foundation for managing and monitoring Hibernate operations in your applications.

Comments