hibernate/hibernate-orm · error · JtaPlatformException
Could not access JTA Transaction to register synchronization
Error message
Could not access JTA Transaction to register synchronization
What it means
Hibernate throws this JtaPlatformException from AbstractJtaPlatform.TransactionManagerBasedSynchronizationStrategy when it must attach a javax.transaction.Synchronization to the current JTA transaction, but getTransactionManager().getTransaction() throws, returns null, or returns a transaction that cannot accept registrations (already completed, rolled back, or marked rollback-only). It means Session work that needs transaction callbacks (flush, before-completion processing, second-level cache synchronization) ran without a usable JTA transaction.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/jta/platform/internal/AbstractJtaPlatform.java:54
private boolean cacheUserTransaction;
private ServiceRegistryImplementor serviceRegistry;
private final JtaSynchronizationStrategy tmSynchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy();
@Override
public void injectServices(@Nonnull ServiceRegistryImplementor serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
private final class TransactionManagerBasedSynchronizationStrategy implements JtaSynchronizationStrategy {
@Override
public void registerSynchronization(Synchronization synchronization) {
try {
getTransactionManager().getTransaction().registerSynchronization( synchronization );
}
catch (Exception e) {
throw new JtaPlatformException( "Could not access JTA Transaction to register synchronization", e );
}
}
@Override
public boolean canRegisterSynchronization() {
return isActive( getTransactionManager() );
}
}
protected ServiceRegistry serviceRegistry() {
return serviceRegistry;
}
protected JndiService jndiService() {
return serviceRegistry().requireService( JndiService.class );
}
protected abstract TransactionManager locateTransactionManager();View on GitHub (pinned to fad1729dce)
Solutions
- Ensure a JTA transaction is begun and still active before Session work: userTransaction.begin(), session operations, then commit()
- Verify hibernate.transaction.jta.platform matches the runtime (JBossAppServerJtaPlatform on WildFly, NarayanaJtaPlatform standalone, etc.)
- Audit code paths that touch the Session after transaction completion and move them inside the transaction boundary
- If it appears after an upgrade, align hibernate-core and the transaction integration library versions
Example fix
// before: flush outside JTA transaction scope
session.flush(); // -> JtaPlatformException: could not access JTA transaction
// after
userTransaction.begin();
try {
session.flush();
userTransaction.commit();
}
catch (Exception e) {
userTransaction.rollback();
} Defensive patterns
Strategy: validation
Validate before calling
// verify an active JTA transaction before Session work that registers synchronizations
if (transactionManager.getStatus() != javax.transaction.Status.STATUS_ACTIVE) {
throw new IllegalStateException("JTA transaction not active (status=" + transactionManager.getStatus() + ")");
}
session.flush(); Try / catch
try {
session.flush();
} catch (JtaPlatformException e) {
// no active JTA transaction, or it already completed
throw new IllegalStateException("Session work attempted outside an active JTA transaction", e);
} Prevention
- Begin the JTA transaction before Session operations in that unit of work
- Set hibernate.transaction.jta.platform explicitly per deployment environment
- Never reuse a Session after its JTA transaction committed or rolled back
- Assert transaction status in integration tests before flushing
When it happens
Trigger: Session.flush()/auto-flush, beforeTransactionCompletion processing, or cache synchronization while no active JTA transaction exists; using the Session after ut.commit()/rollback(); the transaction is in STATUS_MARKED_ROLLBACK or a terminal state; hibernate.transaction.jta.platform configured for a runtime other than the one actually running so getTransactionManager() misbehaves.
Common situations: Spring/JTA apps where the platform property was copied from another server; code that keeps using a Session after the JTA transaction ended; upgrading the app server or Narayana so the previously configured TM no longer works; mixing RESOURCE_LOCAL persistence with leftover JTA platform settings.
Related errors
- Synchronization to register cannot be null
- Exception calling user Synchronization (beforeCompletion): $
- Exception calling user Synchronization (afterCompletion): ${
- Unable to register cleanup Synchronization with TransactionM
- Transaction is not accessible when using JTA with JPA-compli
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c15af8210dd8909d.
Report an issue: GitHub.