{"record":{"id":"ee8ffa2a2f10da3b","repo":"hibernate/hibernate-orm","slug":"primary-key-information-was-missing-for-key-s-o","errorCode":null,"errorMessage":"Primary Key information was missing for key [%s] on table [%s] at KEY_SEQ = %s","messagePattern":"Primary Key information was missing for key \\[(.+?)\\] on table \\[(.+?)\\] at KEY_SEQ = (.+?)","errorType":"exception","errorClass":"SchemaExtractionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/NameSpacePrimaryKeysInformation.java","lineNumber":44,"sourceCode":"\t\tprimaryKeys.put( tableInformation.getName().getTableName().getText(), primaryKeyInformation );\n\t}\n\n\tpublic @Nullable PrimaryKeyInformation getPrimaryKeyInformation(Table table) {\n\t\treturn primaryKeys.get( identifierHelper.toMetaDataObjectName( table.getQualifiedTableName().getTableName() ) );\n\t}\n\n\tpublic @Nullable PrimaryKeyInformation getPrimaryKeyInformation(String tableName) {\n\t\treturn primaryKeys.get( tableName );\n\t}\n\n\tpublic void validate() {\n\t\tfor ( Map.Entry<String, PrimaryKeyInformation> entry : primaryKeys.entrySet() ) {\n\t\t\tfinal var tableName = entry.getKey();\n\t\t\tfinal var primaryKeyInformation = entry.getValue();\n\t\t\tint i = 1;\n\t\t\tfor ( ColumnInformation column : primaryKeyInformation.getColumns() ) {\n\t\t\t\tif ( column == null ) {\n\t\t\t\t\tthrow new SchemaExtractionException(\n\t\t\t\t\t\t\t\"Primary Key information was missing for key [\" +\n\t\t\t\t\t\t\tprimaryKeyInformation.getPrimaryKeyIdentifier() + \"] on table [\" + tableName +\n\t\t\t\t\t\t\t\"] at KEY_SEQ = \" + i\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n}\n","sourceCodeStart":26,"sourceCodeEnd":55,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/NameSpacePrimaryKeysInformation.java#L26-L55","documentation":"SchemaExtractionException from NameSpacePrimaryKeysInformation.validate(): while validating assembled primary-key metadata, the ordered column list of some table's PK contains a null at 1-based position KEY_SEQ = i. Hibernate slots PK columns from DatabaseMetaData.getPrimaryKeys() into positions numbered by KEY_SEQ; a hole means the driver reported non-contiguous, duplicated, or truncated KEY_SEQ values - inconsistent JDBC metadata.","triggerScenarios":"Primary-key extraction on databases/drivers whose getPrimaryKeys() result skips a KEY_SEQ value, duplicates one, or returns fewer rows than the key's column count; the later validate() pass finds the null slot and throws with the key name, table name, and offending position. Seen with certain Oracle/DB2/SQL Server driver versions, partitioned tables, and PostgreSQL inheritance/partition parents whose PK metadata is only partially reported.","commonSituations":"hbm2ddl validate after a driver downgrade; validating against a partitioned parent table; DB2 z/OS with legacy drivers; catalogs left inconsistent by online DDL churn; CI validating against a stale replica.","solutions":["Upgrade/align the JDBC driver with the database version and rerun.","Inspect the PK metadata (SELECT constraint_name, ordinal_position, column_name FROM information_schema.key_column_usage WHERE table_name = '<table>') and rebuild the constraint so ordinal positions are contiguous: ALTER TABLE ... DROP CONSTRAINT ... then ADD CONSTRAINT ... PRIMARY KEY (...).","If the table is partitioned or inherited, validate against a partition/leaf table or exclude it from hbm2ddl validation.","Adopt Flyway/Liquibase for schema management to avoid dependence on driver PK metadata."],"exampleFix":"-- before: driver reports KEY_SEQ 1,3 for orders_pkey -> null at slot 2\nSELECT constraint_name, ordinal_position, column_name\nFROM information_schema.key_column_usage\nWHERE table_name = 'orders';\n\n-- after: rebuild the constraint so catalog rows are contiguous\nALTER TABLE orders DROP CONSTRAINT orders_pkey;\nALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY (id, tenant_id);","handlingStrategy":"validation","validationCode":"// Check KEY_SEQ contiguity for the primary keys of the tables being validated\ntry (Connection c = dataSource.getConnection();\n     ResultSet rs = c.getMetaData().getPrimaryKeys(null, null, \"orders\")) {\n    int expected = 1;\n    while (rs.next()) {\n        if (rs.getShort(\"KEY_SEQ\") != expected) {\n            System.err.println(\"PK metadata hole at KEY_SEQ \" + expected + \" for \" + rs.getString(\"PK_NAME\"));\n        }\n        expected++;\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    new SchemaValidator().validate(metadata, serviceRegistry);\n} catch (SchemaManagementException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Primary Key information was missing\")) {\n        // parse key/table/KEY_SEQ from the message, rebuild the PK constraint, re-run\n    }\n    throw e;\n}","preventionTips":["Keep the JDBC driver aligned with the database version","Avoid hbm2ddl validation on partitioned/inherited parent tables with partial PK metadata","Validate in CI against a schema built by the same migrations used in production"],"tags":["hibernate","schema-management","jdbc-metadata","primary-key","schema-extraction"],"backgroundTag":"jdbc-metadata-extraction","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}