skip to content

JpaTransactionManager

JpaTransactionManager binds the EntityManager together with its JDBC connection, flushes Hibernate at commit, and can share that connection with plain JDBC code. This is what explains whether mixing JPA and JdbcTemplate in one transaction actually works.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is JpaTransactionManager and when do you use it?

level: juniorimportance: must knowfreq 70%

answer

  1. PlatformTransactionManager for JPA
  2. opens EntityManager, begins tx, binds to thread
  3. flush + commit on success, rollback on RuntimeException
  4. Boot auto-configures with single EMF
  5. one persistence context per @Transactional

basics

~10 s

JpaTransactionManager is Spring's PlatformTransactionManager for JPA. It opens an EntityManager, starts a transaction on it, and commits or rolls back when a @Transactional method finishes. Use it when your app persists data through JPA/Hibernate.

solid answer

~40 s

JpaTransactionManager is the PlatformTransactionManager implementation you wire up when your persistence layer is JPA (Hibernate). It's what actually powers @Transactional for JPA code. On a transaction start it obtains an EntityManager from the EntityManagerFactory, begins a resource-local (or JTA-participating) transaction on it, and binds that EntityManager to the current thread so repositories and @PersistenceContext-injected managers reuse the same one. On success it flushes and commits; on a runtime exception it rolls back. In a Spring Boot app that has a single JPA EntityManagerFactory, Boot auto-configures exactly this bean for you, so you rarely instantiate it by hand. You mainly configure it explicitly when you have multiple persistence units and need a manager per EntityManagerFactory.

code

java · 20 lines
java
@Configuration
public class TxConfig {

    // Usually Spring Boot auto-configures this; shown explicitly for clarity.
    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
}

@Service
class OrderService {
    private final OrderRepository orders;
    OrderService(OrderRepository orders) { this.orders = orders; }

    @Transactional // driven by JpaTransactionManager
    public void place(Order o) {
        orders.save(o); // shares the tx-bound EntityManager; flush+commit happen at method end
    }
}

go deeper

for a junior

Know it's the @Transactional engine for JPA: opens an EntityManager, commits or rolls back.

for a middle

Explain thread-binding of the EntityManager so repositories share one persistence context.

for a senior

Discuss default rollback rules, Boot auto-config, and when you'd declare it explicitly (multi-EMF).

for a principal

Frame the PlatformTransactionManager abstraction and per-unit manager selection in a multi-datasource architecture.

## The role Spring's declarative transactions (`@Transactional`) are driven by an abstraction called `PlatformTransactionManager`. `@Transactional` doesn't know how to talk to a database; it delegates to whichever transaction-manager bean is configured. `JpaTransactionManager` is the concrete implementation for the case where your persistence is done through **JPA** (in practice, Hibernate as the JPA provider). ## What it manages In JPA the central object is the `EntityManager` — it represents a *persistence context*, a first-level cache of managed entities plus the unit of work. `EntityManager` instances are created by an `EntityManagerFactory`. `JpaTransactionManager` holds a reference to that `EntityManagerFactory`. When a transaction begins, it: 1. asks the factory for an `EntityManager`, 2. calls `getTransaction().begin()` on it (for a resource-local transaction), 3. and registers the manager with Spring so the rest of the request can find it. ## Why binding matters Spring keeps per-thread state in `TransactionSynchronizationManager`. `JpaTransactionManager` wraps the freshly created `EntityManager` in an `EntityManagerHolder` and binds it under the `EntityManagerFactory` key. Any code that later needs an `EntityManager` — a Spring Data JPA repository, or a bean with `@PersistenceContext EntityManager em` — goes through `EntityManagerFactoryUtils.doGetTransactionalEntityManager(...)`, which finds that same bound holder. That's why every DB operation inside one `@Transactional` method shares **one persistence context and one transaction**. ## Lifecycle end - When the method returns normally, `JpaTransactionManager` triggers a Hibernate **flush** (SQL is sent to the DB) and then **commits** the underlying JDBC transaction. - If a `RuntimeException`/`Error` propagates out (the default rollback rule), it rolls back instead. Checked exceptions do *not* roll back by default — you'd add `rollbackFor`. - Finally the bound `EntityManager` is unbound and closed. ## Spring Boot With a single `DataSource` and a single JPA `EntityManagerFactory`, `JpaTransactionAutoConfiguration`/`HibernateJpaAutoConfiguration` register a `JpaTransactionManager` bean automatically, so you typically write zero configuration. You define it yourself for multi-datasource setups (one manager per unit) or to tune properties. ## When NOT to use it - If you never touch JPA and only use plain JDBC/`JdbcTemplate`, use `DataSourceTransactionManager`. - If you span multiple resources needing two-phase commit, use `JtaTransactionManager`.

  • Does JpaTransactionManager roll back on a checked exception?
    No. By default it only rolls back on unchecked exceptions (RuntimeException and Error). For a checked exception you must set @Transactional(rollbackFor = ...).
  • Who creates the EntityManager used inside the transaction?
    JpaTransactionManager obtains it from the EntityManagerFactory at transaction start, binds it to the thread via TransactionSynchronizationManager, and closes it at the end.

saying these in an interview costs you the question

  • Thinking @Transactional itself opens the connection — it delegates to the transaction manager
  • Claiming JpaTransactionManager rolls back on any exception including checked ones
  • Confusing EntityManagerFactory (long-lived, shared) with EntityManager (per-transaction)

context

open as a page

How does JpaTransactionManager make a Spring Data repository and a @PersistenceContext EntityManager share the same persistence context within one transaction?

level: middleimportance: should knowfreq 45%

basics

~20 s

On transaction start it creates one EntityManager, wraps it in an EntityManagerHolder, and binds it to the thread via TransactionSynchronizationManager keyed by the EntityManagerFactory. All JPA code in that transaction looks up and reuses that same bound EntityManager.

open as a page

When does Hibernate actually send SQL to the database under JpaTransactionManager, and how does flush-at-commit work?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Hibernate batches changes in the persistence context and flushes them as SQL either automatically before queries or when JpaTransactionManager commits. At commit the manager triggers a final flush, then commits the JDBC transaction. Nothing is durable until that commit.

open as a page

Can JdbcTemplate participate in the same transaction as JPA under JpaTransactionManager? How does the connection get shared?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Yes. JpaTransactionManager exposes the JDBC Connection that Hibernate uses and binds it to the DataSource in Spring's resource registry. A JdbcTemplate built on that same DataSource picks up the bound connection, so JDBC and JPA share one transaction and commit together.

open as a page

How do you choose between JpaTransactionManager, DataSourceTransactionManager, and JtaTransactionManager, and what breaks if you pick the wrong one?

level: principalimportance: should knowfreq 30%

basics

~10 s

Use JpaTransactionManager when JPA/Hibernate is your persistence provider so the EntityManager and transaction are managed together. Use DataSourceTransactionManager for pure JDBC. Use JtaTransactionManager only when a transaction must span multiple resources needing two-phase commit.

open as a page