How do I configure hibernate.cfg.xml for a simple application?

To configure hibernate.cfg.xml for a simple Hibernate application, you need to include the essential properties for Hibernate to interact with the database and map your entities.

Below is an example of hibernate.cfg.xml:

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

<hibernate-configuration>
    <session-factory>

        <!-- Database connection settings -->
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testdb</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>

        <!-- Hibernate dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>

        <!-- JDBC connection pool settings -->
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>

        <!-- Enable Hibernate's automatic table creation -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- Show SQL logs in the console -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- Add entity mappings -->
        <mapping class="org.kodejava.hibernate.Student"/>

    </session-factory>
</hibernate-configuration>

Explanation of the Configuration

  1. Database Connection Settings:
    • hibernate.connection.driver_class: Specifies the JDBC driver class (e.g., org.h2.Driver for an H2 database, com.mysql.cj.jdbc.Driver for MySQL, etc.).
    • hibernate.connection.url: JDBC URL to connect to your database.
    • hibernate.connection.username and hibernate.connection.password: Database credentials.
  2. Dialect:
    • hibernate.dialect: Hibernate’s SQL dialect for the specific database (e.g., H2Dialect, MySQLDialect, PostgreSQLDialect, etc.).
  3. Connection Pool:
    • Configures a simple C3P0 connection pool with properties like min_size, max_size, and timeout.
  4. Schema Management:
    • hibernate.hbm2ddl.auto:
      • create: Creates the schema, destroying any existing data.
      • update: Updates the schema, keeping existing data.
      • validate: Validates the schema without making changes.
      • none: Disables automatic schema management.
  5. SQL Output:
    • hibernate.show_sql: Logs executed SQL statements to the console.
    • hibernate.format_sql: Formats SQL logs for better readability.
  6. Entity Mapping:
    • <mapping class="org.kodejava.hibernate.Student"/>: Maps the Student entity to the database.

Using this Configuration

Place the hibernate.cfg.xml file in the src/main/resources directory (or in the root of your classpath). You can then use it to build a SessionFactory in your application:

SessionFactory factory = new Configuration()
        .configure("hibernate.cfg.xml")  // Load the config file
        .addAnnotatedClass(Student.class)  // Add annotated entity classes
        .buildSessionFactory();

This will allow Hibernate to connect to the database and manage your entities as per the configuration specified.

How do I create my first Hibernate entity using annotations?

To create a basic Hibernate entity using annotations, follow these steps:

1. Add Required Dependencies

Ensure you have added the required dependencies for Hibernate, JPA (jakarta.persistence), and any database (e.g., H2 for testing) in your pom.xml. For example:

<dependencies>
    <!-- Hibernate Core -->
    <dependency>
        <groupId>org.hibernate.orm</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>6.4.4.Final</version>
    </dependency>
    <!-- H2 Database -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>2.2.224</version>
        <scope>runtime</scope>
    </dependency>
    <!-- JPA API -->
    <dependency>
        <groupId>jakarta.persistence</groupId>
        <artifactId>jakarta.persistence-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

2. Create an Entity Class

An entity class represents a table in the database and should be annotated with @Entity. For example:

package org.kodejava.hibernate;

import jakarta.persistence.*;

@Entity
@Table(name = "students")  // Maps to a table named 'students'
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // Auto-incremented primary key
    private Long id;

    @Column(name = "name", nullable = false)  // Maps field to a column
    private String name;

    // Default constructor
    public Student() {}

    // Constructor with arguments
    public Student(String name) {
        this.name = name;
    }

    // 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;
    }
}

Explanation of Annotations

  1. @Entity: Marks the class as an entity that maps to a database table.
  2. @Table(name = "table_name"): Specifies the name of the database table (optional). If omitted, the table will use the class name.
  3. @Id: Marks the field as the primary key.
  4. @GeneratedValue(strategy = GenerationType.IDENTITY): Specifies auto-generation of primary key values.
  5. @Column(name = "column_name"): Maps a class field to a specific table column (optional). Omitting this will map the field name to a column with the same name.

3. Specify Entity in Hibernate Configuration

Ensure this entity is configured in your hibernate.cfg.xml file, or programmatically added when building the SessionFactory. In the XML file, include:

<mapping class="org.kodejava.hibernate.Student" />

4. Persist Data Using Hibernate

You can now use Hibernate to perform CRUD operations on this entity. For example, to save a Student:

package org.kodejava.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateApp {
    public static void main(String[] args) {
        // Create a SessionFactory and configure Hibernate
        SessionFactory factory = new Configuration()
                .configure("hibernate.cfg.xml")  // Load the configuration file
                .addAnnotatedClass(Student.class)  // Add annotated class
                .buildSessionFactory();

        // Open session
        try (Session session = factory.openSession()) {
            // Create a new student entity
            Student student = new Student("John Doe");

            // Start a transaction
            session.beginTransaction();

            // Save the student to the database
            session.persist(student);

            // Commit the transaction
            session.getTransaction().commit();

            System.out.println("Student saved successfully with ID: " + student.getId());
        } finally {
            factory.close();  // Close the factory
        }
    }
}

Summary

By using annotations like @Entity, @Table, @Id, and @Column, you can define the structure of your database table directly within the Java entity class. Hibernate simplifies interacting with the database and reduces the amount of boilerplate code involved.

How do I set up Hibernate in a Maven project?

1. Introduction

In this post, we’ll walk through the process of setting up a basic Hibernate project using Maven. Hibernate is a powerful ORM (Object-Relational Mapping) tool for Java, and it’s often used to simplify database interactions in enterprise applications.

2. Prerequisites

  • Java JDK 17 or later
  • Maven installed
  • A code editor (e.g., IntelliJ IDEA, Eclipse)
  • A basic understanding of Java classes and interfaces

3. Create a Maven Project

If you’re using a terminal:

mvn archetype:generate -DgroupId=org.kodejava.hibernate \
    -DartifactId=hibernate-setup \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DinteractiveMode=false

Navigate to the project folder:

cd hibernate-setup

4. Add Hibernate Dependencies

Edit your pom.xml to include the Hibernate Core dependency and H2 Database (for testing):

<dependencies>
    <!-- Hibernate Core -->
    <dependency>
        <groupId>org.hibernate.orm</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>6.4.4.Final</version>
    </dependency>
    <!-- H2 Database -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>2.2.224</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.persistence</groupId>
        <artifactId>jakarta.persistence-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

5. Create Hibernate Configuration

Create a file named hibernate.cfg.xml under src/main/resources:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection properties -->
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testdb</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>

        <!-- Hibernate properties -->
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- Manage schema updates automatically -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- Specify annotated entity classes -->
        <mapping class="org.kodejava.hibernate.Student" />
    </session-factory>
</hibernate-configuration>

6. Define a Simple Entity Class

package org.kodejava.hibernate;

import jakarta.persistence.*;

@Entity
@Table(name = "students")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    public Student() {}
    public Student(String name) { this.name = name; }

    // getters and setters
}

7. Write a Main Class to Test Hibernate

package org.kodejava.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateMain {
    public static void main(String[] args) {
        SessionFactory factory = new Configuration()
                .configure("hibernate.cfg.xml")
                .addAnnotatedClass(Student.class)
                .buildSessionFactory();

        Session session = factory.openSession();

        try {
            Student student = new Student("Alice");
            session.beginTransaction();
            session.persist(student);
            session.getTransaction().commit();
            System.out.println("Student saved successfully!");
        } finally {
            session.close();
            factory.close();
        }
    }
}

8. Run the Program

Compile and run the application:

mvn compile exec:java -Dexec.mainClass="org.kodejava.hibernate.HibernateMain"

9. Summary

You’ve now set up a basic Hibernate project using Maven and saved a simple entity to an in-memory database. In future posts, we’ll expand on this by adding relationships, custom queries, and performance tuning techniques.

How do I use Hibernate’s Restriction.in criterion?

This example demonstrate the use of Hibernate’s Restriction.in criterion. This restriction will query for some record based on a collection of parameter defined for a specific property of the bean.

package org.kodejava.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.HibernateException;
import org.hibernate.Criteria;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.kodejava.hibernate.model.Genre;

import java.util.List;

public class RestrictionInDemo {
    public static Session getSession() throws HibernateException {
        String cfg = "hibernate.cfg.xml";
        SessionFactory sessionFactory = new Configuration().configure(cfg)
                .buildSessionFactory();
        return sessionFactory.openSession();
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        try (Session session = getSession()) {
            // Create a Criteria an add an in constraint for the property
            // id. This in restrictions will return genre with id 1, 2, 3
            // and 4.
            Criteria criteria = session.createCriteria(Genre.class)
                    .add(Restrictions.in("id", 1L, 2L, 3L, 4L));

            List<Genre> result = criteria.list();
            for (Genre genre : result) {
                System.out.println(genre);
            }
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.9.Final</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I use min, max, avg and sum Projections?

The code below demonstration the use of Projections.min(), Projections.max(), Projections.avg() and Projections.sum().

package org.kodejava.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.HibernateException;
import org.hibernate.Criteria;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Projections;
import org.kodejava.hibernate.model.Track;

public class MinMaxAvgSumProjectionsDemo {
    public static Session getSession() throws HibernateException {
        String cfg = "hibernate.cfg.xml";
        SessionFactory sessionFactory = new Configuration().configure(cfg)
                .buildSessionFactory();
        return sessionFactory.openSession();
    }

    public static void main(String[] args) {
        try (Session session = getSession()) {
            Criteria criteria = session.createCriteria(Track.class)
                    .setProjection(Projections.max("duration"));
            Integer maxDuration = (Integer) criteria.uniqueResult();
            System.out.println("Max Track Duration = " + maxDuration);

            criteria.setProjection(Projections.min("duration"));
            Integer minDuration = (Integer) criteria.uniqueResult();
            System.out.println("Min Track Duration = " + minDuration);

            criteria.setProjection(Projections.avg("duration"));
            Double avgDuration = (Double) criteria.uniqueResult();
            System.out.println("Avg Track Duration = " + avgDuration);

            criteria.setProjection(Projections.sum("duration"));
            Long totalDuration = (Long) criteria.uniqueResult();
            System.out.println("Total Track Duration = " + totalDuration);
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.9.Final</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version>
    </dependency>
</dependencies>

Maven Central Maven Central