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

  1. 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
  2. Or stop needing JTA: use a resource-local setup (non-JTA DataSource, JDBC coordinator) when no transaction manager exists
  3. Verify the expected JNDI bindings for your platform exist (java:/TransactionManager, java:jboss/TransactionManager, java:comp/UserTransaction, ...)
  4. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/78c5a34f0f575a82. Report an issue: GitHub.