hibernate/hibernate-orm · critical · TransactionException

JDBC begin transaction failed:

Error message

JDBC begin transaction failed: 

What it means

Thrown when Hibernate cannot start a physical JDBC transaction: AbstractLogicalConnectionImplementor.begin() calls Connection.setAutoCommit(false) (unless the provider disables autocommit) and wraps any SQLException in this TransactionException. The message itself is generic; the real cause is always chained as getCause(). The transaction never became ACTIVE, so nothing was begun on the database side.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/AbstractLogicalConnectionImplementor.java:71

		getResourceRegistry().releaseResources();
	}

	// PhysicalJdbcTransaction impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	protected abstract Connection getConnectionForTransactionManagement();

	@Override
	public void begin() {
		try {
			if ( !doConnectionsFromProviderHaveAutoCommitDisabled() ) {
				CONNECTION_LOGGER.preparingToBeginViaSetAutoCommitFalse();
				getConnectionForTransactionManagement().setAutoCommit( false );
				CONNECTION_LOGGER.transactionBegunViaSetAutoCommitFalse();
			}
			status = TransactionStatus.ACTIVE;
		}
		catch( SQLException e ) {
			throw new TransactionException( "JDBC begin transaction failed: ", e );
		}
	}

	@Override
	public void commit() {
		if ( isPhysicallyConnected() ) {
			commitConnection();
		}
		else {
			errorIfClosed();
			status = TransactionStatus.COMMITTED;
		}
		afterCompletion();
	}

	private void commitConnection() {
		try {
			CONNECTION_LOGGER.preparingToCommitViaConnectionCommit();

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect the chained SQLException (SQLState + vendor error code) to identify the real failure before changing anything
  2. Fix pool settings: set maxLifetime below the DB idle timeout and enable checkout validation (isValid / test query)
  3. If running under JTA, configure hibernate.transaction.coordinator_class=jta so Hibernate does not drive setAutoCommit itself
  4. If transient (connection class 08xxx), retry the whole unit of work on a fresh Session/EntityManager

Example fix

// before
em.getTransaction().begin(); // TransactionException: JDBC begin transaction failed

// after
try {
  em.getTransaction().begin();
} catch (org.hibernate.TransactionException te) {
  Throwable root = te.getCause();
  while (root.getCause() != null) root = root.getCause();
  // root is the SQLException: classify (transient vs fatal) and retry with a new EntityManager if transient
}
// plus pool hygiene: hikari maxLifetime < DB wait_timeout, connection validation enabled
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the pooled connection before beginning, on a session you are about to use
em.unwrap(org.hibernate.Session.class).doReturningWork(conn -> conn.isValid(1));

Type guard

static boolean isJdbcBeginFailure(Throwable t) {
  return t instanceof org.hibernate.TransactionException
      && t.getMessage() != null
      && t.getMessage().startsWith("JDBC begin transaction failed");
}

Try / catch

try {
  tx.begin();
} catch (org.hibernate.TransactionException e) {
  Throwable root = e.getCause();
  while (root != null && root.getCause() != null) root = root.getCause();
  // root is the SQLException: classify by SQLState (08xxx = connection, transient) and
  // either retry with a fresh EntityManager or surface the real cause to ops
}

Prevention

When it happens

Trigger: session.beginTransaction() / EntityTransaction.begin() on a resource-local (JDBC) Hibernate session where setAutoCommit(false) throws: the pool handed out an already-closed or network-dead connection, the DB is restarting/failing over, the driver forbids setAutoCommit (e.g. a connection already enlisted in an XA transaction), or the connection was reclaimed mid-flight.

Common situations: MySQL wait_timeout recycling connections while the pool maxLifetime is larger; DB restart or failover under load; reusing a Session after an earlier exception left its connection broken; accidentally using Hibernate's JDBC transaction coordinator on a JTA/XA-managed connection.

Related errors


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