hibernate/hibernate-orm · error · PersistenceException
Connection [%s] passed back to %s was not the one obtained [
Error message
Connection [%s] passed back to %s was not the one obtained [%s] from it
What it means
Thrown by Hibernate's schema management tooling (SchemaExport/SchemaUpdate/SchemaMigrator) when the JDBC Connection handed back to JdbcConnectionAccessConnectionProviderImpl.releaseConnection() is not the exact same instance obtainConnection() returned. The wrapper hands out one single Connection for the whole schema operation and enforces identity on release, because it must restore the connection's original auto-commit state before giving it back to the ConnectionProvider. A different instance therefore means the contract obtain/release-same-connection was broken somewhere in between.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionAccessConnectionProviderImpl.java:72
}
}
catch (SQLException ignore) {
wasInitiallyAutoCommit = false;
}
JDBC_LOGGER.initialAutoCommit( wasInitiallyAutoCommit );
this.wasInitiallyAutoCommit = wasInitiallyAutoCommit;
}
@Override
public Connection obtainConnection() throws SQLException {
return jdbcConnection;
}
@Override
public void releaseConnection(Connection connection) throws SQLException {
if ( connection != this.jdbcConnection ) {
throw new PersistenceException(
String.format(
"Connection [%s] passed back to %s was not the one obtained [%s] from it",
connection,
JdbcConnectionAccessConnectionProviderImpl.class.getName(),
jdbcConnection
)
);
}
// Reset auto-commit
if ( !wasInitiallyAutoCommit ) {
try {
if ( jdbcConnection.getAutoCommit() ) {
jdbcConnection.setAutoCommit( false );
}
}
catch (SQLException exception) {
JDBC_LOGGER.unableToResetAutoCommitDisabled( exception );View on GitHub (pinned to fad1729dce)
Solutions
- Pass the exact Connection instance returned by obtainConnection() to releaseConnection() — never a wrapper or delegate.
- Remove or unwrap connection proxies around schema generation; unwrap to the underlying vendor connection before releasing.
- If you implement JdbcConnectionAccess or GenerationTarget yourself, obtain and release through the same provider path so instance identity holds.
- Align/upgrade your integration (e.g. Hibernate Reactive, custom tools) with the matching hibernate-core version — identity handling has been patched across releases.
Example fix
// before: releasing a wrapped connection
final Connection conn = access.obtainConnection();
access.releaseConnection( new LoggingConnectionWrapper( conn ) ); // PersistenceException
// after: release the exact instance that was obtained
final Connection conn = access.obtainConnection();
try {
// run DDL against conn
}
finally {
access.releaseConnection( conn );
} Defensive patterns
Strategy: try-catch
Try / catch
try {
schemaExport.execute( EnumSet.of( TargetType.DATABASE ), metadata );
}
catch ( PersistenceException e ) {
if ( e.getMessage() != null && e.getMessage().contains( "was not the one obtained" ) ) {
// a GenerationTarget or custom access released a different Connection instance
throw new IllegalStateException( "Schema tooling connection mismatch", e );
}
throw e;
} Prevention
- Hold the Connection returned by obtainConnection() in a local variable and release exactly that reference in finally.
- Never wrap or proxy connections between obtain and release during schema generation.
- Use one ConnectionProvider for the whole schema operation; do not mix sources.
- Avoid custom GenerationTargets unless you replicate Hibernate's obtain/release pairing exactly.
When it happens
Trigger: Running schema generation/migration with a ConnectionProvider-backed JdbcConnectionAccess, then calling releaseConnection() with a connection other than the one obtained: a wrapped/proxied connection (logging, metrics, tenant-routing delegates), a different pooled connection, or custom GenerationTarget/JdbcConnectionAccess code that swaps the instance. Also triggered by pools that return a fresh dynamic proxy per close() path so == identity fails.
Common situations: Custom GenerationTarget or custom schema-management integrations (e.g. reactive/tooling wrappers) that wrap connections; connection pools issuing non-identical proxies; user code mixing connections from two providers during hbm2ddl.
Related errors
- User-provided Connection via JdbcConnectionAccessProvidedCon
- Error accessing user-provided Connection via JdbcConnectionA
- Could not set provided connection [%s] to auto-commit mode (
- JDBC driver does not support named parameters for setArray.
- Configuration property hibernate.jdbc.time_zone value [{}] i
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f6f6bc6c7638174a.
Report an issue: GitHub.