Question 16 · Section 16

What is EntityManager and How Does It Differ from Session

EntityManager and Session are two interfaces for working with ORM in Java. EntityManager is the standard JPA interface, while Session is a Hibernate-specific implementation. Und...

Language versions: English Russian Ukrainian

Overview

EntityManager and Session are two interfaces for working with ORM in Java. EntityManager is the standard JPA interface, while Session is a Hibernate-specific implementation. Understanding the differences helps you choose the right abstraction.


Junior Level

What is EntityManager

EntityManager is the JPA standard interface for working with entities. It is defined in the JPA specification and works with any JPA provider (Hibernate, EclipseLink, OpenJPA).

Note: in Hibernate 5 / Java EE, the javax.persistence package is used; in Hibernate 6 / Jakarta EE - jakarta.persistence. Examples below use jakarta.

// JPA standard - works with any provider
@PersistenceContext
private EntityManager em;

em.persist(user);
em.merge(user);
em.remove(user);
User found = em.find(User.class, 1L);

What is Session

Session is a Hibernate-specific interface. It provides additional capabilities not available in the standard JPA.

// Hibernate-specific
Session session = entityManager.unwrap(Session.class);
session.save(user);
session.update(user);
session.delete(user);
User found = session.get(User.class, 1L);

Main Difference

  EntityManager Session
Standard JPA (jakarta.persistence) Hibernate (org.hibernate)
Portability Any JPA provider Hibernate only
Methods persist, merge, remove, find save, update, delete, get
Extra features No doWork(), replicate(), etc.

How to Get Session from EntityManager

Session session = entityManager.unwrap(Session.class);

Middle Level

Method Comparison

EntityManager (JPA)          Session (Hibernate)
-----------------           -----------------
persist()                   save()
merge()                     update(), saveOrUpdate()
remove()                    delete()
find()                      get()
createQuery()               createQuery()
createNativeQuery()         createSQLQuery()
flush()                     flush()
clear()                     clear()
contains()                  contains()
detach()                    evict()
refresh()                   refresh()

When to Use EntityManager

// For portability between JPA providers
@Repository
public class UserRepository {
    @PersistenceContext
    private EntityManager em;

    public void save(User user) {
        em.persist(user);  // standard method
    }
}

When to Use Session

// For Hibernate-specific features
Session session = entityManager.unwrap(Session.class);

// Direct Connection access
session.doWork(connection -> {
    // JDBC operations
    PreparedStatement stmt = connection.prepareStatement("...");
});

// Batch operations
session.doReturningWork(connection -> {
    // return result
    return result;
});

// Native Hibernate capabilities
session.byMultipleIds(User.class)
    .multiLoad(ids);

Additional Session Methods

Session session = entityManager.unwrap(Session.class);

// doWork - work with Connection
session.doWork(new Work() {
    public void execute(Connection connection) {
        // JDBC operations
    }
});

// replicate - copy entity
session.replicate(user, ReplicationMode.OVERWRITE);

// getIdentifier - get ID
Serializable id = session.getIdentifier(user);

// isConnected - connection check
boolean connected = session.isConnected();

Senior Level

Internal Implementation

// In Hibernate 5.2+, Session and EntityManager share internal
// implementation. Session implements EntityManager, rather than wrapping it.

EntityManager - interface from JPA specification (jakarta.persistence)
Session - interface from Hibernate (org.hibernate)

When to Use Session

// 1. Native SQL with result return
Session session = entityManager.unwrap(Session.class);
NativeQuery<User> query = session.createNativeQuery(
    "SELECT * FROM users WHERE created_at > :date", User.class);
query.setParameter("date", date);

// 2. Multi-load (Hibernate 5.1+)
List<User> users = session.byMultipleIds(User.class)
    .enableCheckCache(true)
    .multiLoad(List.of(1L, 2L, 3L));

// 3. Scrollable results (for large data)
ScrollableResults<User> results = session.createQuery("FROM User", User.class)
    .setFetchSize(100)
    .scroll(ScrollMode.FORWARD_ONLY);

// 4. Statistics
Statistics stats = session.getSessionFactory().getStatistics();

When NOT to Use Session

// If Hibernate-specific features not needed
// If provider change is possible
// For standard CRUD operations
// In libraries/frameworks (violates abstraction)

Best Practices

EntityManager by default
unwrap(Session) when Hibernate features needed
Standard methods for portability
Session for batch/native operations
Session for statistics and monitoring

Session when Hibernate features not needed
Mixing without reason
unwrap() in every method (better to extract)
Direct Session usage in libraries

Interview Cheat Sheet

Must know:

  • EntityManager - JPA standard (jakarta.persistence), works with any provider
  • Session - Hibernate-specific interface, additional capabilities
  • Session obtained via entityManager.unwrap(Session.class)
  • EntityManager methods: persist, merge, remove, find; Session: save, update, delete, get
  • Session provides: doWork() (JDBC), multi-load, scrollable results, statistics
  • EntityManager by default, Session when Hibernate features needed

Frequent follow-up questions:

  • When to use Session? Native SQL with result return, multi-load, scrollable results, statistics, batch operations
  • When NOT to use Session? Standard CRUD, provider change possible, libraries/frameworks
  • Why doWork()? Direct access to JDBC Connection for operations JPA doesn’t support
  • What changed in Hibernate 5.2+? Session and EntityManager share internal implementation

Red flags (DO NOT say):

  • “I always use Session instead of EntityManager” - ties to Hibernate
  • “I mix them without reason” - violates JPA abstraction
  • “unwrap() in every method” - better to extract into separate component
  • “Session in libraries” - violates portability

Related topics:

  • [[7. Describe the Entity Lifecycle in Hibernate]]
  • [[14. What is the Difference Between persist() and merge()]]
  • [[12. What is Dirty Checking in Hibernate]]
  • [[17. How to Implement Optimistic Locking in JPA]]