How do I use SessionFactory and Session in Hibernate 6?

Hibernate ORM 6 introduces several changes to its API compared to previous versions, especially in how SessionFactory and Session are used due to compliance with Jakarta EE and its updated imports (jakarta.persistence.*).
Here’s a simple guide to using SessionFactory and Session in Hibernate 6:

1. Add Hibernate Dependencies

Make sure to include the Hibernate 6 dependencies in your project. If you’re using Maven, the dependency would look like this:

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.4.4.Final</version>
</dependency>

2. Configure Hibernate

Use or Properties for configuration:hibernate.cfg.xml

Example: hibernate.cfg.xml

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/your_database</property>
        <property name="hibernate.connection.username">your_username</property>
        <property name="hibernate.connection.password">your_password</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
    </session-factory>
</hibernate-configuration>

Alternatively, use Java configuration with Properties:

Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
properties.put("hibernate.connection.url", "jdbc:postgresql://localhost:5432/your_database");
properties.put("hibernate.connection.username", "your_username");
properties.put("hibernate.connection.password", "your_password");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "update");

3. Create a SessionFactory

Starting with Hibernate 6, the SessionFactory should be built using the StandardServiceRegistryBuilder and MetadataSources.

Here’s an example:

Using hibernate.cfg.xml:

package org.kodejava.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        // Build the ServiceRegistry using hibernate.cfg.xml
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml") // Loads hibernate.cfg.xml by default
                .build();

        try {
            // Build SessionFactory
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            StandardServiceRegistryBuilder.destroy(registry);
            throw new ExceptionInInitializerError("SessionFactory build failed: " + e.getMessage());
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        getSessionFactory().close();
    }
}

Using Java configuration with Properties:

package org.kodejava.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;

import java.util.Properties;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        // Create Hibernate properties
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
        properties.put("hibernate.connection.url", "jdbc:postgresql://localhost:5432/your_database");
        properties.put("hibernate.connection.username", "your_username");
        properties.put("hibernate.connection.password", "your_password");
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.hbm2ddl.auto", "update");

        // Build the ServiceRegistry
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .applySettings(properties)
                .build();

        try {
            // Build SessionFactory
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            StandardServiceRegistryBuilder.destroy(registry);
            throw new ExceptionInInitializerError("SessionFactory build failed: " + e.getMessage());
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        getSessionFactory().close();
    }
}

4. Use SessionFactory to Get a Session

A Session represents a single unit of work with the database. In Hibernate 6, the usage involves a similar pattern to previous versions.

package org.kodejava.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class App {
    public static void main(String[] args) {
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // Obtain a session
        try (Session session = sessionFactory.openSession()) {
            // Begin transaction
            session.beginTransaction();

            // Perform operations (e.g., save entities)
            MyEntity entity = new MyEntity();
            entity.setName("Example");
            session.persist(entity);

            // Commit the transaction
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Shutdown the session factory
            HibernateUtil.shutdown();
        }
    }
}

5. Entity Example

Ensure your entity classes are annotated correctly with Jakarta Persistence annotations (jakarta.persistence.*).

package org.kodejava.hibernate;

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

@Entity
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String 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;
    }
}

Key Updates in Hibernate 6

  1. Jakarta Imports: Hibernate moved from javax.persistence.* to jakarta.persistence.*.
  2. Default Configuration: The APIs are adaptive, but the configuration process is largely unchanged.
  3. Session Persistence: The Session.persist(Object) method is preferred over deprecated methods like save(Object).

By following these steps, you can effectively use SessionFactory and Session in Hibernate 6 for your application.

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 create Hibernate’s SessionFactory?

When creating an application the use Hibernate to manage our application persistence object we’ll need a SessionFactory. This factory creates or open a session to talk to a database.

To create a SessionFactory we can define the configuration in hibernate.properties, hibernate.cfg.xml or create it programmatically. In this example we’ll use the hibernate.cfg.xml configuration file, which is mostly use when creating Hibernate application.

Below is our session configuration files.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- JDBC connection settings -->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/musicdb</property>
        <property name="connection.username">root</property>
        <property name="connection.password" />

        <!-- JDBC connection pool, use Hibernate internal connection pool -->
        <property name="connection.pool_size">5</property>

        <!-- Defines the SQL dialect used in Hibernate's application -->
        <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</property>

        <!-- Display and format all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <!-- Mapping to hibernate mapping files -->
        <mapping resource="org/kodejava/hibernate/mapping/Label.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Now we have the configuration file done, let’s create a helper class that will configure and build the SessionFactory object. This helper will be used in other Hibernate example in this site.

package org.kodejava.hibernate;

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

public class SessionFactoryHelper {
    private static final SessionFactory sessionFactory;

    static {
        try {
            // Build a SessionFactory object from session-factory config
            // defined in the hibernate.cfg.xml file. In this file we
            // register the JDBC connection information, connection pool,
            // hibernate dialect that we used and the mapping to our
            // hbm.xml file for each pojo (plain old java object).
            Configuration config = new Configuration();
            sessionFactory = config.configure().buildSessionFactory();
        } catch (Throwable e) {
            System.err.println("Error in creating SessionFactory object."
                    + e.getMessage());
            throw new ExceptionInInitializerError(e);
        }
    }

    public static void main(String[] args) {
        Session session = SessionFactoryHelper.getSessionFactory()
                .getCurrentSession();
        System.out.println("session = " + session);
    }

    /**
     * A static method for other application to get SessionFactory object
     * initialized in this helper class.
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

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