hibernate/hibernate-orm · error · HibernateException

Unable to perform isolated work

Error message

Unable to perform isolated work

What it means

HibernateException from JtaIsolationDelegate: the isolated work itself (run inside a suspended-transaction window under JTA) threw a non-Hibernate Throwable, which is wrapped with this message; HibernateExceptions rethrow unchanged. The cause holds the real failure — typically a SQLException from the isolated statement or a defect in custom Work code.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaIsolationDelegate.java:119

		try {
			// suspend current JTA transaction, if any
			surroundingTransaction = suspend();
		}
		catch ( SystemException systemException ) {
			throw new TransactionException( "Unable to suspend current JTA transaction", systemException );
		}

		Throwable exception = null;
		try {
			return callable.call();
		}
		catch ( HibernateException he ) {
			exception = he;
			throw he;
		}
		catch ( Throwable throwable ) {
			exception = throwable;
			throw new HibernateException( "Unable to perform isolated work", throwable );
		}
		finally {
			try {
				// resume the JTA transaction we suspended
				resume( surroundingTransaction );
			}
			catch ( Throwable throwable ) {
				// if the actual work had an error, use that; otherwise throw this error
				if ( exception == null ) {
					throw new TransactionException( "Unable to resume suspended transaction", throwable );
				}
				else {
					exception.addSuppressed( throwable );
				}
			}
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Unwrap and inspect the cause — it is the actual exception (SQL error, missing table, NPE) with the failing statement
  2. Create or grant the schema object the isolated work touches (generator table/sequence) and keep migrations in sync with @TableGenerator/@SequenceGenerator mappings
  3. Run hibernate.hbm2ddl.auto=validate at startup to catch missing objects before the first insert
  4. For custom Work implementations, fix the defect the cause points to

Example fix

// before
@TableGenerator(name = "ids", table = "id_gen")
// id_gen missing in the JTA-managed schema -> 'Unable to perform isolated work' on first persist

// after
// migration: CREATE TABLE id_gen (k VARCHAR(64) PRIMARY KEY, v BIGINT NOT NULL);
//            INSERT INTO id_gen (k, v) VALUES ('ids', 0);
// plus: hibernate.hbm2ddl.auto=validate to fail at startup instead of first insert
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast at startup: verify generator objects exist before the first insert
Session s = sessionFactory.openSession();
s.doWork(conn -> {
  try (var rs = conn.createStatement()
          .executeQuery("select 1 from id_gen where k = 'ids'")) { // generator table probe
    if (!rs.next()) throw new IllegalStateException("ID generator table not initialized");
  }
});

Type guard

static SQLException findSqlException(Throwable t) {
  for (Throwable c = t; c != null; c = c.getCause()) {
    if (c instanceof SQLException s) return s;
  }
  return null;
}

Try / catch

try {
  em.persist(entity);
  em.flush();
} catch (org.hibernate.HibernateException e) {
  // 'Unable to perform isolated work': unwrap the cause — it carries the real SQL/defect;
  // fix the schema object or the Work implementation, then retry in a new transaction
}

Prevention

When it happens

Trigger: Isolated work under JTA fails: a table-based ID generator's isolated SELECT/UPDATE hitting a missing table or missing privileges, a missing sequence during information extraction, SQL errors in custom Work executed via the delegate, or an NPE inside the work.

Common situations: Schema created without the generator table/sequence under a JTA deployment; renamed schema objects after migration; read-restricted DB users lacking grants on generator tables; first persist after deployment surfacing the missing object.

Related errors


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