hibernate/hibernate-orm · error · SchemaManagementException
Attempt to resolve foreign key metadata from JDBC metadata f
Error message
Attempt to resolve foreign key metadata from JDBC metadata failed to find column mappings for foreign key named [%s]
What it means
Thrown by Hibernate's JDBC schema extractor while reading foreign-key metadata: DatabaseMetaData.getImportedKeys() reported a foreign key by name, but after grouping the result-set rows for that key, zero referencing/referenced column pairs could be collected, so ForeignKeyInformation cannot be built. It is a consistency check between what the driver advertises and what Hibernate can map, and almost always indicates a JDBC driver/database mismatch or an exotic foreign key rather than a broken entity mapping.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/AbstractInformationExtractorImpl.java:1637
protected static class ForeignKeyBuilderImpl implements ForeignKeyBuilder {
private final Identifier foreignKeyIdentifier;
private final List<ForeignKeyInformation.ColumnReferenceMapping> columnMappingList = new ArrayList<>();
public ForeignKeyBuilderImpl(Identifier foreignKeyIdentifier) {
this.foreignKeyIdentifier = foreignKeyIdentifier;
}
@Override
public ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced) {
columnMappingList.add( new ColumnReferenceMappingImpl( referencing, referenced ) );
return this;
}
@Override
public ForeignKeyInformationImpl build() {
if ( columnMappingList.isEmpty() ) {
throw new SchemaManagementException(
"Attempt to resolve foreign key metadata from JDBC metadata failed to find " +
"column mappings for foreign key named [" + foreignKeyIdentifier.getText() + "]"
);
}
return new ForeignKeyInformationImpl( foreignKeyIdentifier, columnMappingList );
}
}
private QualifiedTableName extractPrimaryKeyTableName(ResultSet resultSet) throws SQLException {
return new QualifiedTableName(
toIdentifier( resultSet.getString( getResultSetPrimaryKeyCatalogLabel() ) ),
toIdentifier( resultSet.getString( getResultSetPrimaryKeySchemaLabel() ) ),
toIdentifier( resultSet.getString( getResultSetPrimaryKeyTableLabel() ) ) );
}
private QualifiedTableName extractTableName(ResultSet resultSet) throws SQLException {
return new QualifiedTableName(
toIdentifier( resultSet.getString( getResultSetCatalogLabel() ) ),View on GitHub (pinned to fad1729dce)
Solutions
- Upgrade the JDBC driver to a version matching the database server, then rerun validate/update.
- Inspect the named FK in the database (SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE CONSTRAINT_NAME = '<fk name>') and drop/recreate it so its column metadata is consistent.
- Verify the connection resolves the expected catalog/schema (hibernate.default_catalog / hibernate.default_schema) so the key is not read from an unexpected namespace.
- If the driver cannot be fixed, move schema management to Flyway/Liquibase, which diffs scripts instead of JDBC FK metadata.
Example fix
// before: DB server upgraded, driver kept old -> getImportedKeys() returns a key with no columns // pom.xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> // after: driver matched to the server major version <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.4.0</version> </dependency>
Defensive patterns
Strategy: try-catch
Validate before calling
// Before running hbm2ddl validate/update, probe FK metadata for the tables involved
try (Connection c = dataSource.getConnection();
ResultSet rs = c.getMetaData().getImportedKeys(null, null, "orders")) {
while (rs.next()) {
String fk = rs.getString("FK_NAME");
if (fk == null || rs.getString("FKCOLUMN_NAME") == null || rs.getString("PKCOLUMN_NAME") == null) {
System.err.println("Incomplete JDBC FK metadata for " + fk + " - fix driver/schema before hbm2ddl");
}
}
} Try / catch
try {
new SchemaValidator().validate(metadata, serviceRegistry);
} catch (SchemaManagementException e) {
if (e.getMessage() != null && e.getMessage().contains("failed to find column mappings for foreign key")) {
// driver metadata problem, not mapping drift: capture the FK name, align driver/DB, re-run
}
throw e;
} Prevention
- Keep the JDBC driver version in lockstep with the database server version
- Run hbm2ddl validate in CI against a schema produced by the exact migrations used in production
- Prefer Flyway/Liquibase for production schema management instead of hbm2ddl validate/update
When it happens
Trigger: Running schema tooling that extracts live metadata (hibernate.hbm2ddl.auto=validate or update, SchemaValidator/SchemaUpdate, or a custom InformationExtractor pass). AbstractInformationExtractorImpl groups getImportedKeys() rows per FK name, calls addColumnMapping per row, and ForeignKeyBuilder.build() throws when the group's columnMappingList is empty. Produced by drivers returning FK rows with null/unknown FKCOLUMN_NAME or PKCOLUMN_NAME, cross-schema or self-referencing keys poorly reported by old drivers, or catalog stats left stale by renames.
Common situations: hbm2ddl validate in CI with an old MySQL Connector/J, jTDS, or a driver version lagging behind an upgraded DB server; Oracle schemas where the FK references a table in another schema; MariaDB/MySQL after table renames; mixing DB version N+1 with driver version N-1.
Related errors
- Attempt to resolve JDBC metadata failed to find columns for
- Error performing schema management [persistence unit: {}]
- Unrecognized 'hibernate.hbm2ddl.jdbc_metadata_extraction_str
- Primary Key information was missing for key [%s] on table [%
- Export identifier [%s] encountered more than once
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a7dbefe4cbe15199.
Report an issue: GitHub.