Package org.springframework.orm.jpa

# Class JpaTransactionManager

java.lang.Object
org.springframework.transaction.support.AbstractPlatformTransactionManager
org.springframework.orm.jpa.JpaTransactionManager

All Implemented Interfaces:
  `Serializable`, `org.springframework.beans.factory.Aware`, `org.springframework.beans.factory.BeanFactoryAware`, `org.springframework.beans.factory.InitializingBean`, `org.springframework.transaction.ConfigurableTransactionManager`, `org.springframework.transaction.PlatformTransactionManager`, `org.springframework.transaction.support.ResourceTransactionManager`, `org.springframework.transaction.TransactionManager`

public class JpaTransactionManager extends org.springframework.transaction.support.AbstractPlatformTransactionManager implements org.springframework.transaction.support.ResourceTransactionManager, org.springframework.beans.factory.BeanFactoryAware, org.springframework.beans.factory.InitializingBean
`PlatformTransactionManager` implementation for a single JPA `EntityManagerFactory`. Binds a JPA EntityManager from the specified factory to the thread, potentially allowing for one thread-bound EntityManager per factory. `SharedEntityManagerCreator` and `@PersistenceContext` are aware of thread-bound entity managers and participate in such transactions automatically. Using either is required for JPA access code supporting this transaction management mechanism.

This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through `JtaTransactionManager`) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.

This transaction manager also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access JPA and services which use plain JDBC (without being aware of JPA)! Application code needs to stick to the same simple Connection lookup pattern as with `DataSourceTransactionManager` (i.e. `DataSourceUtils.getConnection(javax.sql.DataSource)` or going through a `TransactionAwareDataSourceProxy`). Note that this requires a vendor-specific `JpaDialect` to be configured.

Note: To be able to register a DataSource's Connection for plain JDBC code, this instance needs to be aware of the DataSource (`setDataSource(javax.sql.DataSource)`). The given DataSource should obviously match the one used by the given EntityManagerFactory. This transaction manager will autodetect the DataSource used as the connection factory of the EntityManagerFactory, so you usually don't need to explicitly specify the "dataSource" property.

This transaction manager supports nested transactions via JDBC Savepoints. The `"nestedTransactionAllowed"` flag defaults to "true" but should rather be "false", as nested transactions will just apply to the JDBC Connection, not to the JPA EntityManager and its cached entity objects and related context. As of Spring Framework 7.0, the default will be "false" in alignment with other transaction managers, requiring an explicit switch to "true" if you want to use nested transactions for JDBC access code which participates in JPA transactions (provided that your JDBC driver supports savepoints). Note that JPA itself does not support nested transactions! Hence, do not expect JPA access code to semantically participate in a nested transaction.

Since:
  2.0
Author:
  Juergen Hoeller
See Also:
  - `setEntityManagerFactory(jakarta.persistence.EntityManagerFactory)`
  - `setDataSource(javax.sql.DataSource)`
  - `LocalEntityManagerFactoryBean`
  - `SharedEntityManagerBean`
  - `DataSourceUtils.getConnection(javax.sql.DataSource)`
  - `DataSourceUtils.releaseConnection(java.sql.Connection, javax.sql.DataSource)`
  - `JdbcTemplate`
  - `JdbcTransactionManager`
  - `JtaTransactionManager`
  - Serialized Form

## Field Summary

### Fields inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager

`logger, SYNCHRONIZATION_ALWAYS, SYNCHRONIZATION_NEVER, SYNCHRONIZATION_ON_ACTUAL_TRANSACTION`

## Constructor Summary

Constructors
Constructor
Description
`JpaTransactionManager()`
Create a new JpaTransactionManager instance.
`JpaTransactionManager(EntityManagerFactory emf)`
Create a new JpaTransactionManager instance.

## Method Summary

Modifier and Type
Method
Description
`void`
`afterPropertiesSet()`
Eagerly initialize the JPA dialect, creating a default one for the specified EntityManagerFactory if none set.
`protected void`
`closeEntityManagerAfterFailedBegin(org.springframework.orm.jpa.JpaTransactionManager.JpaTransactionObject txObject)`
Close the current transaction's EntityManager.
`protected EntityManager`
`createEntityManagerForTransaction()`
Create a JPA EntityManager to be used for a transaction.
`protected void`
`doBegin(Object transaction, org.springframework.transaction.TransactionDefinition definition)`
`protected void`
`doCleanupAfterCompletion(Object transaction)`
`protected void`
`doCommit(org.springframework.transaction.support.DefaultTransactionStatus status)`
`protected Object`
`doGetTransaction()`
`protected void`
`doResume(Object transaction, Object suspendedResources)`
`protected void`
`doRollback(org.springframework.transaction.support.DefaultTransactionStatus status)`
`protected void`
`doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus status)`
`protected Object`
`doSuspend(Object transaction)`
`DataSource`
`getDataSource()`
Return the JDBC DataSource that this instance manages transactions for.
`EntityManagerFactory`
`getEntityManagerFactory()`
Return the EntityManagerFactory that this instance should manage transactions for.
`JpaDialect`
`getJpaDialect()`
Return the JPA dialect to use for this transaction manager.
`Map<String,Object>`
`getJpaPropertyMap()`
Allow `Map` access to the JPA properties to be passed to the persistence provider, with the option to add or override specific entries.
`String`
`getPersistenceUnitName()`
Return the name of the persistence unit to manage transactions for, if any.
`Object`
`getResourceFactory()`
`protected boolean`
`isExistingTransaction(Object transaction)`
`protected final EntityManagerFactory`
`obtainEntityManagerFactory()`
Obtain the EntityManagerFactory for actual use.
`void`
`setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)`
Retrieves an EntityManagerFactory by persistence unit name, if none set explicitly.
`void`
`setDataSource(DataSource dataSource)`
Set the JDBC DataSource that this instance should manage transactions for.
`void`
`setEntityManagerFactory(EntityManagerFactory emf)`
Set the EntityManagerFactory that this instance should manage transactions for.
`void`
`setEntityManagerInitializer(Consumer<EntityManager> entityManagerInitializer)`
Specify a callback for customizing every `EntityManager` resource created for a new transaction managed by this `JpaTransactionManager`.
`void`
`setJpaDialect(JpaDialect jpaDialect)`
Set the JPA dialect to use for this transaction manager.
`void`
`setJpaProperties(Properties jpaProperties)`
Specify JPA properties, to be passed into `EntityManagerFactory.createEntityManager(Map)` (if any).
`void`
`setJpaPropertyMap(Map<String,?> jpaProperties)`
Specify JPA properties as a Map, to be passed into `EntityManagerFactory.createEntityManager(Map)` (if any).
`void`
`setPersistenceUnitName(String persistenceUnitName)`
Set the name of the persistence unit to manage transactions for.
`protected boolean`
`shouldCommitOnGlobalRollbackOnly()`
This implementation returns "true": a JPA commit will properly handle transactions that have been marked rollback-only at a global level.

### Methods inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager

`commit, determineTimeout, getDefaultTimeout, getTransaction, getTransactionExecutionListeners, getTransactionSynchronization, invokeAfterCompletion, isFailEarlyOnGlobalRollbackOnly, isGlobalRollbackOnParticipationFailure, isNestedTransactionAllowed, isRollbackOnCommitFailure, isValidateExistingTransaction, prepareForCommit, prepareSynchronization, registerAfterCompletionWithExistingTransaction, resume, rollback, setDefaultTimeout, setFailEarlyOnGlobalRollbackOnly, setGlobalRollbackOnParticipationFailure, setNestedTransactionAllowed, setRollbackOnCommitFailure, setTransactionExecutionListeners, setTransactionSynchronization, setTransactionSynchronizationName, setValidateExistingTransaction, suspend, triggerBeforeCommit, triggerBeforeCompletion, useSavepointForNestedTransaction`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.springframework.transaction.ConfigurableTransactionManager

`addListener`

### Methods inherited from interface org.springframework.transaction.PlatformTransactionManager

`commit, getTransaction, rollback`

## Constructor Details

### JpaTransactionManager

public JpaTransactionManager()
Create a new JpaTransactionManager instance.

An EntityManagerFactory has to be set to be able to use it.

See Also:
  - `setEntityManagerFactory(jakarta.persistence.EntityManagerFactory)`

### JpaTransactionManager

public JpaTransactionManager(EntityManagerFactory emf)
Create a new JpaTransactionManager instance.

Parameters:
  `emf` - the EntityManagerFactory to manage transactions for

## Method Details

### setEntityManagerFactory

public void setEntityManagerFactory(@Nullable EntityManagerFactory emf)
Set the EntityManagerFactory that this instance should manage transactions for.

Alternatively, specify the persistence unit name of the target EntityManagerFactory. By default, a default EntityManagerFactory will be retrieved by finding a single unique bean of type EntityManagerFactory in the containing BeanFactory.

See Also:
  - `setPersistenceUnitName(java.lang.String)`

### getEntityManagerFactory

@Nullable public EntityManagerFactory getEntityManagerFactory()
Return the EntityManagerFactory that this instance should manage transactions for.

### obtainEntityManagerFactory

protected final EntityManagerFactory obtainEntityManagerFactory()
Obtain the EntityManagerFactory for actual use.

Returns:
  the EntityManagerFactory (never `null`)
Throws:
  `IllegalStateException` - in case of no EntityManagerFactory set
Since:
  5.0

### setPersistenceUnitName

public void setPersistenceUnitName(@Nullable String persistenceUnitName)
Set the name of the persistence unit to manage transactions for.

This is an alternative to specifying the EntityManagerFactory by direct reference, resolving it by its persistence unit name instead. If no EntityManagerFactory and no persistence unit name have been specified, a default EntityManagerFactory will be retrieved by finding a single unique bean of type EntityManagerFactory.

See Also:
  - `setEntityManagerFactory(jakarta.persistence.EntityManagerFactory)`

### getPersistenceUnitName

@Nullable public String getPersistenceUnitName()
Return the name of the persistence unit to manage transactions for, if any.

### setJpaProperties

public void setJpaProperties(@Nullable Properties jpaProperties)
Specify JPA properties, to be passed into `EntityManagerFactory.createEntityManager(Map)` (if any).

Can be populated with a String "value" (parsed via PropertiesEditor) or a "props" element in XML bean definitions.

See Also:
  - `EntityManagerFactory.createEntityManager(java.util.Map)`

### setJpaPropertyMap

public void setJpaPropertyMap(@Nullable Map<String,?> jpaProperties)
Specify JPA properties as a Map, to be passed into `EntityManagerFactory.createEntityManager(Map)` (if any).

Can be populated with a "map" or "props" element in XML bean definitions.

See Also:
  - `EntityManagerFactory.createEntityManager(java.util.Map)`

### getJpaPropertyMap

public Map<String,Object> getJpaPropertyMap()
Allow `Map` access to the JPA properties to be passed to the persistence provider, with the option to add or override specific entries.

Useful for specifying entries directly, for example via `jpaPropertyMap[myKey]`.

### setDataSource

public void setDataSource(@Nullable DataSource dataSource)
Set the JDBC DataSource that this instance should manage transactions for. The DataSource should match the one used by the JPA EntityManagerFactory: for example, you could specify the same JNDI DataSource for both.

If the EntityManagerFactory uses a known DataSource as its connection factory, the DataSource will be autodetected: You can still explicitly specify the DataSource, but you don't need to in this case.

A transactional JDBC Connection for this DataSource will be provided to application code accessing this DataSource directly via DataSourceUtils or JdbcTemplate. The Connection will be taken from the JPA EntityManager.

Note that you need to use a JPA dialect for a specific JPA implementation to allow for exposing JPA transactions as JDBC transactions.

The DataSource specified here should be the target DataSource to manage transactions for, not a TransactionAwareDataSourceProxy. Only data access code may work with TransactionAwareDataSourceProxy, while the transaction manager needs to work on the underlying target DataSource. If there's nevertheless a TransactionAwareDataSourceProxy passed in, it will be unwrapped to extract its target DataSource.

See Also:
  - `EntityManagerFactoryInfo.getDataSource()`
  - `setJpaDialect(org.springframework.orm.jpa.JpaDialect)`
  - `TransactionAwareDataSourceProxy`
  - `DataSourceUtils`
  - `JdbcTemplate`

### getDataSource

@Nullable public DataSource getDataSource()
Return the JDBC DataSource that this instance manages transactions for.

### setJpaDialect

public void setJpaDialect(@Nullable JpaDialect jpaDialect)
Set the JPA dialect to use for this transaction manager. Used for vendor-specific transaction management and JDBC connection exposure.

If the EntityManagerFactory uses a known JpaDialect, it will be autodetected: You can still explicitly specify the DataSource, but you don't need to in this case.

The dialect object can be used to retrieve the underlying JDBC connection and thus allows for exposing JPA transactions as JDBC transactions.

See Also:
  - `EntityManagerFactoryInfo.getJpaDialect()`
  - `JpaDialect.beginTransaction(jakarta.persistence.EntityManager, org.springframework.transaction.TransactionDefinition)`
  - `JpaDialect.getJdbcConnection(jakarta.persistence.EntityManager, boolean)`

### getJpaDialect

public JpaDialect getJpaDialect()
Return the JPA dialect to use for this transaction manager.

### setEntityManagerInitializer

public void setEntityManagerInitializer(Consumer<EntityManager> entityManagerInitializer)
Specify a callback for customizing every `EntityManager` resource created for a new transaction managed by this `JpaTransactionManager`.

This is an alternative to a factory-level `EntityManager` customizer and to a `JpaVendorAdapter`-level `postProcessEntityManager` callback, enabling specific customizations of transactional resources.

Since:
  5.3
See Also:
  - `createEntityManagerForTransaction()`
  - `AbstractEntityManagerFactoryBean.setEntityManagerInitializer(java.util.function.Consumer<jakarta.persistence.EntityManager>)`
  - `JpaVendorAdapter.postProcessEntityManager(jakarta.persistence.EntityManager)`

### setBeanFactory

public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory) throws org.springframework.beans.BeansException
Retrieves an EntityManagerFactory by persistence unit name, if none set explicitly. Falls back to a default EntityManagerFactory bean if no persistence unit specified.

Specified by:
  `setBeanFactory` in interface `org.springframework.beans.factory.BeanFactoryAware`
Throws:
  `org.springframework.beans.BeansException`
See Also:
  - `setPersistenceUnitName(java.lang.String)`

### afterPropertiesSet

public void afterPropertiesSet()
Eagerly initialize the JPA dialect, creating a default one for the specified EntityManagerFactory if none set. Auto-detect the EntityManagerFactory's DataSource, if any.

Specified by:
  `afterPropertiesSet` in interface `org.springframework.beans.factory.InitializingBean`

### getResourceFactory

public Object getResourceFactory()

Specified by:
  `getResourceFactory` in interface `org.springframework.transaction.support.ResourceTransactionManager`

### doGetTransaction

protected Object doGetTransaction()

Specified by:
  `doGetTransaction` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### isExistingTransaction

protected boolean isExistingTransaction(Object transaction)

Overrides:
  `isExistingTransaction` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doBegin

protected void doBegin(Object transaction, org.springframework.transaction.TransactionDefinition definition)

Specified by:
  `doBegin` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### createEntityManagerForTransaction

protected EntityManager createEntityManagerForTransaction()
Create a JPA EntityManager to be used for a transaction.

The default implementation checks whether the EntityManagerFactory is a Spring proxy and delegates to `EntityManagerFactoryInfo.createNativeEntityManager(java.util.Map<?, ?>)` if possible which in turns applies `JpaVendorAdapter.postProcessEntityManager(EntityManager)`.

See Also:
  - `EntityManagerFactory.createEntityManager()`

### closeEntityManagerAfterFailedBegin

protected void closeEntityManagerAfterFailedBegin(org.springframework.orm.jpa.JpaTransactionManager.JpaTransactionObject txObject)
Close the current transaction's EntityManager. Called after a transaction begin attempt failed.

Parameters:
  `txObject` - the current transaction

### doSuspend

protected Object doSuspend(Object transaction)

Overrides:
  `doSuspend` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doResume

protected void doResume(@Nullable Object transaction, Object suspendedResources)

Overrides:
  `doResume` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### shouldCommitOnGlobalRollbackOnly

protected boolean shouldCommitOnGlobalRollbackOnly()
This implementation returns "true": a JPA commit will properly handle transactions that have been marked rollback-only at a global level.

Overrides:
  `shouldCommitOnGlobalRollbackOnly` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doCommit

protected void doCommit(org.springframework.transaction.support.DefaultTransactionStatus status)

Specified by:
  `doCommit` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doRollback

protected void doRollback(org.springframework.transaction.support.DefaultTransactionStatus status)

Specified by:
  `doRollback` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doSetRollbackOnly

protected void doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus status)

Overrides:
  `doSetRollbackOnly` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`

### doCleanupAfterCompletion

protected void doCleanupAfterCompletion(Object transaction)

Overrides:
  `doCleanupAfterCompletion` in class `org.springframework.transaction.support.AbstractPlatformTransactionManager`