What is the difference between EntityManager and EntityManagerFactory?
In Java Persistence API (JPA), both EntityManager and EntityManagerFactory are fundamental components for managing persistence operations and interacting with the underlying database. While closely related, they serve distinct purposes and have different lifecycles and thread-safety characteristics.
Understanding JPA Basics
JPA is a specification for managing relational data in Java applications. It defines a set of interfaces and annotations that allow developers to map Java objects to database tables, known as object-relational mapping (ORM). The core of JPA revolves around the concept of a persistence context, which is a set of managed entity instances and their lifecycle.
EntityManagerFactory
The EntityManagerFactory is responsible for creating EntityManager instances. It acts as a factory for EntityManager objects. Typically, an application has only one EntityManagerFactory per persistence unit, and it is an expensive object to create. Therefore, it should be created once at application startup and reused throughout the application's lifetime.
- Thread-safe: Multiple threads can safely access and use the same EntityManagerFactory instance.
- Long-lived: It should be initialized once and exist for the entire duration of the application.
- Resource-intensive: Creating an EntityManagerFactory involves loading configurations, establishing connections, and preparing resources, making it a costly operation.
- Not directly involved in persistence operations: It does not interact directly with entities or the database for CRUD operations; its primary role is to create EntityManager instances.
Code Example: Creating an EntityManagerFactory
import javax.persistence.Persistence;
import javax.persistence.EntityManagerFactory;
public class JpaUtil {
private static final String PERSISTENCE_UNIT_NAME = "my-persistence-unit";
private static EntityManagerFactory factory;
public static EntityManagerFactory getEntityManagerFactory() {
if (factory == null) {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
return factory;
}
public static void shutdown() {
if (factory != null) {
factory.close();
}
}
}
EntityManager
The EntityManager is the primary interface for interacting with the persistence context. It manages the lifecycle of entity instances, performs CRUD (Create, Read, Update, Delete) operations, and synchronizes changes with the database. Each EntityManager instance represents a persistence context, which is a set of managed entities.
- Not thread-safe: An EntityManager instance is not designed to be shared across multiple threads. Each thread should obtain its own EntityManager instance.
- Short-lived: It is typically created per request, per transaction, or per business operation and closed when the operation completes.
- Lightweight: Creating an EntityManager is relatively inexpensive compared to creating an EntityManagerFactory.
- Directly involved in persistence operations: It provides methods for persisting, finding, merging, and removing entities, and for querying the database.
Code Example: Using an EntityManager
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
public class UserService {
public void createUser(User user) {
EntityManagerFactory factory = JpaUtil.getEntityManagerFactory();
EntityManager em = factory.createEntityManager();
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
em.persist(user); // Persist a new user
tx.commit();
} catch (RuntimeException e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
throw e;
} finally {
em.close();
}
}
public User findUser(Long id) {
EntityManagerFactory factory = JpaUtil.getEntityManagerFactory();
EntityManager em = factory.createEntityManager();
try {
return em.find(User.class, id); // Find a user by ID
} finally {
em.close();
}
}
}
Key Differences
| Feature | EntityManagerFactory | EntityManager |
|---|---|---|
| Purpose | Creates EntityManager instances | Performs persistence operations |
| Lifecycle | Long-lived (application scope) | Short-lived (transaction/request scope) |
| Thread-Safety | Thread-safe | Not thread-safe |
| Creation Cost | High (expensive) | Low (lightweight) |
| Number per App | Typically one per persistence unit | Many (one per transaction/request) |
| Direct DB Interaction | No | Yes |
Conclusion
In summary, the EntityManagerFactory acts as a robust, thread-safe, and long-lived factory that sets up the JPA environment and provides EntityManager instances. The EntityManager, on the other hand, is a lightweight, non-thread-safe, and short-lived interface that directly interacts with the database to manage entity lifecycles within a specific persistence context. Understanding their distinct roles and lifecycles is crucial for effectively implementing JPA in enterprise applications.