hibernate/hibernate-orm · critical · JtaPlatformException

Could not obtain Narayana UserTransaction instance

Error message

Could not obtain Narayana UserTransaction instance

What it means

NarayanaJtaPlatform.locateUserTransaction() reflectively invokes the static userTransaction() on com.arjuna.ats.jta.UserTransaction. JtaPlatformException('Could not obtain Narayana UserTransaction instance') indicates the Arjuna JTA facade is missing or uninitialized, so Hibernate cannot supply a UserTransaction for programmatic transaction demarcation.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/jta/platform/internal/NarayanaJtaPlatform.java:46

					.getMethod( "transactionManager" )
					.invoke( null );
		}
		catch ( Exception e ) {
			throw new JtaPlatformException( "Could not obtain Narayana TransactionManager instance", e );
		}
	}

	@Override
	protected UserTransaction locateUserTransaction() {
		try {
			return (UserTransaction) serviceRegistry()
					.requireService( ClassLoaderService.class )
					.classForName( UT_CLASS_NAME )
					.getMethod( "userTransaction" )
					.invoke( null );
		}
		catch ( Exception e ) {
			throw new JtaPlatformException( "Could not obtain Narayana UserTransaction instance", e );
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add org.jboss.narayana.jta:narayana-jta
  2. Bootstrap Narayana before any Hibernate session usage
  3. If you demarcate via Spring's JtaTransactionManager, make sure it resolves the UserTransaction itself and Hibernate's platform is consistent
  4. Validate class presence at startup: Class.forName("com.arjuna.ats.jta.UserTransaction")

Example fix

// before: JTA facade missing -> JtaPlatformException at first transaction
// after (pom.xml):
<dependency>
    <groupId>org.jboss.narayana.jta</groupId>
    <artifactId>narayana-jta</artifactId>
    <version>7.0.2.Final</version>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

Class.forName("com.arjuna.ats.jta.UserTransaction");
// static accessor must return a UT instance
Class.forName("com.arjuna.ats.jta.UserTransaction").getMethod("userTransaction").invoke(null);

Prevention

When it happens

Trigger: NarayanaJtaPlatform configured while com.arjuna.ats.jta.UserTransaction is not loadable; the UserTransaction is requested before Narayana initialized the transaction service; shading or classpath pruning dropping com.arjuna.ats.jta.*.

Common situations: Same family as the Narayana TM error: pruned dependencies, partially initialized Narayana in tests, mismatched versions after upgrades.

Related errors


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