Core Java

EntityManagerFactory vs SessionFactory

In the world of Java application development, interacting with databases efficiently is critical. Two key components often come into play when working with Object-Relational Mapping (ORM) frameworks: EntityManagerFactory from the Java Persistence API (JPA) and SessionFactory from Hibernate. These components are central to managing sessions, transactions, and database operations. However, their usage, capabilities, and underlying implementations differ significantly.

Let us delve into understanding the distinctions between Java EntityManagerFactory vs SessionFactory to help you make an informed decision for your project needs.

1. Overview

When building Java applications that interact with relational databases, developers often use Object-Relational Mapping (ORM) frameworks like Hibernate or JPA. Central to these frameworks are the EntityManagerFactory (JPA) and SessionFactory (Hibernate), which are responsible for creating and managing database sessions. Understanding their differences is crucial for selecting the right tool for your application’s architecture.

2. What Is EntityManagerFactory?

The EntityManagerFactory is part of the Java Persistence API (JPA), which is a standardized ORM solution for Java applications. It serves as a factory for EntityManager instances. Each EntityManager is a lightweight, thread-safe object used for database operations like persisting, updating, deleting, and querying data.

2.1 Key Features

Here are the main features:

  • Provides integration with JPA-compliant providers (e.g., EclipseLink, Hibernate).
  • Supports both resource-local and JTA (Java Transaction API) transactions.
  • Defined using a persistence.xml configuration file.

2.2 Code Example

Let’s take a look at the sample code example.

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class JpaExample {
    public static void main(String[] args) {
        // Create EntityManagerFactory using the persistence unit
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
        EntityManager em = emf.createEntityManager();
        
        // Start a transaction
        em.getTransaction().begin();
        System.out.println("Transaction started with EntityManager!");
        
        // Perform database operations (CRUD)
        
        em.getTransaction().commit();
        System.out.println("Transaction committed!");

        // Close resources
        em.close();
        emf.close();
    }
}

2.2.1 Code Explanation

The provided code demonstrates how to use EntityManagerFactory and EntityManager in a JPA-based Java application. Here’s a breakdown of its functionality:

The main method starts by creating an EntityManagerFactory instance using the Persistence.createEntityManagerFactory() method. This method takes the name of the persistence unit (defined in the persistence.xml file) as an argument. The EntityManagerFactory is a heavyweight, thread-safe object that manages the lifecycle of EntityManager instances.

Next, an EntityManager instance is created using the emf.createEntityManager() method. The EntityManager is a lightweight, non-thread-safe object that interacts with the database. It is responsible for performing operations such as persisting, updating, querying, and deleting entities.

The code then begins a transaction by calling em.getTransaction().begin(). Transactions are necessary to group a series of operations into a single, atomic unit, ensuring data consistency and integrity.

At this point, you would typically include database operations, such as creating, reading, updating, or deleting entities. For simplicity, these operations are not included in this code snippet.

Once the database operations are complete, the transaction is committed using em.getTransaction().commit(). This step saves the changes to the database and makes them permanent. A message is printed to the console to indicate that the transaction was successfully committed.

Finally, the code closes the EntityManager and EntityManagerFactory instances using em.close() and emf.close(). Closing these resources is crucial to release database connections and avoid resource leaks.

3. What Is SessionFactory?

The SessionFactory is a central concept in Hibernate, a popular ORM framework for Java. It is a heavyweight, thread-safe factory responsible for creating Session objects. Each Session is a single-threaded object used to interact with the database.

3.1 Key Features

Here are the main features:

  • Tightly coupled with Hibernate, providing direct access to its advanced features.
  • Requires a hibernate.cfg.xml or programmatic configuration.
  • Does not follow the JPA standard but offers more granular control.

3.2 Code Example

Let’s take a look at the sample code example.

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

public class HibernateExample {
    public static void main(String[] args) {
        // Create SessionFactory from configuration
        SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        Session session = sessionFactory.openSession();

        // Start a transaction
        session.beginTransaction();
        System.out.println("Transaction started with Session!");

        // Perform database operations (CRUD)

        session.getTransaction().commit();
        System.out.println("Transaction committed!");

        // Close resources
        session.close();
        sessionFactory.close();
    }
}

3.2.1 Code Explanation

The provided code demonstrates how to use the Hibernate framework to interact with a database. It highlights the creation and usage of the SessionFactory and Session objects for database operations. Here’s a detailed explanation:

The program begins by creating a SessionFactory instance using Hibernate’s Configuration class. The configure() method loads the configuration settings from the hibernate.cfg.xml file, which defines database connection properties and Hibernate mappings.

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-configuration>
    <session-factory>
        <!-- JDBC connection settings -->
        <property name="hibernate.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.url">jdbc:mysql://localhost:3306/your_database_name</property>
        <property name="hibernate.username">your_username</property>
        <property name="hibernate.password">your_password</property>

        <!-- Hibernate settings -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- Annotated class mapping -->
        <mapping class="com.yourpackage.YourEntityClass"/>
    </session-factory>
</hibernate-configuration>

The buildSessionFactory() method initializes the factory, which is a thread-safe, heavyweight object responsible for creating Session instances. Next, a Session is created by calling sessionFactory.openSession(). The Session is a lightweight, single-threaded object used to interact with the database. It acts as a bridge between the application and the database, managing operations like querying, saving, updating, or deleting records.

A transaction is then started using session.beginTransaction(). Transactions group multiple database operations into a single unit of work, ensuring data consistency and atomicity. A message is printed to indicate that the transaction has begun.

At this stage, the application would typically perform database operations (CRUD – Create, Read, Update, Delete). However, these operations are omitted in this example for simplicity.

After completing the database operations, the transaction is committed using session.getTransaction().commit(). This step makes the changes permanent in the database. A message is printed to indicate the successful commit of the transaction.

Finally, the Session and SessionFactory are closed using session.close() and sessionFactory.close(). Closing these resources is essential to release database connections and prevent resource leaks, ensuring the application runs efficiently.

4. Comparing EntityManagerFactory and SessionFactory

AspectEntityManagerFactorySessionFactory
FrameworkJPAHibernate
API TypeStandardized (javax.persistence or jakarta.persistence)Hibernate-specific
Session ManagementManages lightweight EntityManagerManages heavyweight Session
TransactionsSupports JTA and resource-local transactionsDirect Hibernate transaction management
PerformanceDesigned for JPA portabilityOptimized for Hibernate-specific features
PortabilityPortable across ORM implementationsHibernate-specific and non-portable

5. Conclusion

The choice between EntityManagerFactory and SessionFactory depends on your application’s requirements. You should use EntityManagerFactory if you aim for portability and adherence to Java standards with JPA. On the other hand, opt for SessionFactory if you want to leverage Hibernate-specific features and are committed to using Hibernate. Both tools are powerful for managing persistence in Java applications, and understanding their differences ensures you select the one that aligns best with your architecture and development goals.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button