hibernate/hibernate-orm · critical · JtaPlatformInaccessibleException
Unable to access TransactionManager or UserTransaction to ma
Error message
Unable to access TransactionManager or UserTransaction to make physical transaction delegate
What it means
The coordinator builds its physical transaction delegate lazily by asking the configured JtaPlatform for a TransactionManager (or UserTransaction when preferUserTransactions); when the retrieval returns null it throws JtaPlatformInaccessibleException. The JtaPlatform class itself resolved, but its lookups (usually JNDI) failed, so Hibernate has no handle to drive transactions. It fires on the first transactional operation of a JTA-configured SessionFactory.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorImpl.java:223
}
@Override
@Nonnull
public TransactionDriver getTransactionDriverControl() {
if ( physicalTransactionDelegate == null ) {
physicalTransactionDelegate = makePhysicalTransactionDelegate();
}
return physicalTransactionDelegate;
}
@Nonnull
private TransactionDriverControlImpl makePhysicalTransactionDelegate() {
final var adapter =
preferUserTransactions
? getTransactionAdapterPreferringUserTransaction()
: getTransactionAdapterPreferringTransactionManager();
if ( adapter == null ) {
throw new JtaPlatformInaccessibleException(
"Unable to access TransactionManager or UserTransaction to make physical transaction delegate"
);
}
else {
return new TransactionDriverControlImpl( adapter );
}
}
@Nullable
private JtaTransactionAdapter getTransactionAdapterPreferringTransactionManager() {
final var adapter = makeTransactionManagerAdapter();
if ( adapter == null ) {
JTA_LOGGER.unableToAccessTransactionManagerTryingUserTransaction();
return makeUserTransactionAdapter();
}
else {
return adapter;
}View on GitHub (pinned to fad1729dce)
Solutions
- Set the platform explicitly, e.g. hibernate.transaction.jta.platform=org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform (with Narayana) or the class matching your container
- Or stop needing JTA: use a resource-local setup (non-JTA DataSource, JDBC coordinator) when no transaction manager exists
- Verify the expected JNDI bindings for your platform exist (java:/TransactionManager, java:jboss/TransactionManager, java:comp/UserTransaction, ...)
- Upgrade Hibernate - newer versions auto-detect more containers
Example fix
// before (Java SE: no platform detected, first tx fails)
Map<String, Object> cfg = Map.of(
"hibernate.transaction.coordinator_class", "jta");
// after (Narayana on the classpath)
Map<String, Object> cfg = Map.of(
"hibernate.transaction.coordinator_class", "jta",
"hibernate.transaction.jta.platform",
"org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform"); Defensive patterns
Strategy: validation
Validate before calling
// Fail fast at startup instead of on first transaction use
try {
Object tm = new InitialContext().lookup("java:/TransactionManager"); // adjust name per platform
if ( tm == null ) {
throw new IllegalStateException("Set hibernate.transaction.jta.platform explicitly");
}
}
catch (NamingException e) {
throw new IllegalStateException("No JTA TransactionManager bound; do not use coordinator_class=jta", e);
} Type guard
static boolean canRetrieveJtaTransactionManager(JtaPlatform platform) {
return platform != null && platform.retrieveTransactionManager() != null;
} Try / catch
try {
session.beginTransaction();
}
catch (JtaPlatformInaccessibleException e) {
// configuration error, not transient: fix hibernate.transaction.jta.platform / JNDI and rebuild
throw new IllegalStateException("JTA platform misconfigured", e);
} Prevention
- Set hibernate.transaction.jta.platform explicitly in SE and unusual containers
- Use resource-local (JDBC) transactions when no transaction manager exists
- Add a startup smoke test that opens a session and begins/rolls back a transaction
When it happens
Trigger: Bootstrap with coordinator_class=jta (or a jta-data-source) in an environment where JtaPlatform.retrieveTransactionManager()/retrieveUserTransaction() return null: wrong or missing hibernate.transaction.jta.platform, JNDI names not bound (plain Java SE with no TM), or an unrecognized container whose JNDI names the bundled platform does not know.
Common situations: Java SE bootstrap with the jta coordinator but no transaction manager; deploying to an app server version with changed JNDI names; a typo in the jta.platform setting; test harnesses without a JTA provider.
Related errors
- illegal value for configuration setting 'hibernate.connectio
- The {storageEngine} storage engine is not supported
- Could not instantiate event listener '{}'
- Unable to instantiate StatementObserver - {}
- No ServiceRegistry was passed to Configuration#buildSessionF
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/78c5a34f0f575a82.
Report an issue: GitHub.