Hibernate SessionFactory is thread safe
Yes, Hibernate SessionFactory is designed to be thread-safe. The SessionFactory instance can be shared among multiple threads and can be used to create Session objects. It is a heavyweight object that should be created once and kept for the entire application runtime. Creating multiple instances of SessionFactory is not recommended because it involves significant overhead and can lead to performance issues.
A single SessionFactory instance can be used to manage the lifecycle of many Session instances, ensuring efficient management of database connections and other resources. This design makes it ideal for use in multi-threaded environments.
Table of Contents
Hibernate SessionFactory Example
Here is an example demonstrating the thread-safe nature of SessionFactory
Create Hibernate Configuration File (hibernate.cfg.xml):
xml
<?xml version="1.0" encoding="UTF-8"?>
<!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">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Specify the HBMs and annotated classes here -->
<mapping class="com.example.MyEntity"/>
</session-factory>
</hibernate-configuration>
Create Entity Class (MyEntity.java):
java
package com.example;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class MyEntity {
@Id
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;
}
}
Load Configuration and Build SessionFactory
3. Load Configuration and Build SessionFactory (HibernateUtil.java):
java
package com.example;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Thread-Safe Usage of SessionFactory:
java
package com.example;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Main {
public static void main(String[] args) {
// Get the SessionFactory
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
// Create multiple threads to demonstrate thread-safe usage
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
// Start a transaction
transaction = session.beginTransaction();
// Create a new MyEntity object
MyEntity entity = new MyEntity();
entity.setId((long) (Math.random() * 1000));
entity.setName(Thread.currentThread().getName());
// Save the entity
session.save(entity);
// Commit the transaction
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
// Close the session
session.close();
}
}).start();
}
}
}