{"record":{"id":"895cc15e655b54a0","repo":"hibernate/hibernate-orm","slug":"could-not-locate-table-information-for-s-895cc1","errorCode":null,"errorMessage":"Could not locate table information for %s","messagePattern":"Could not locate table information for (.+?)","errorType":"exception","errorClass":"SchemaExtractionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/DatabaseInformationImpl.java","lineNumber":183,"sourceCode":"\t@Override\n\tpublic PrimaryKeyInformation locatePrimaryKeyInformation(QualifiedTableName tableName) {\n\t\treturn extractor.getPrimaryKey( locateNonNullTableInformation( tableName ) );\n\t}\n\n\t@Override\n\tpublic Iterable<ForeignKeyInformation> locateForeignKeyInformation(QualifiedTableName tableName) {\n\t\treturn extractor.getForeignKeys( locateNonNullTableInformation( tableName ) );\n\t}\n\n\t@Override\n\tpublic Iterable<IndexInformation> locateIndexesInformation(QualifiedTableName tableName) {\n\t\treturn extractor.getIndexes( locateNonNullTableInformation( tableName ) );\n\t}\n\n\tprivate TableInformation locateNonNullTableInformation(QualifiedTableName tableName) {\n\t\tfinal TableInformation tableInformation = locateTableInformation( tableName );\n\t\tif ( tableInformation == null ) {\n\t\t\tthrow new SchemaExtractionException( \"Could not locate table information for \" + tableName );\n\t\t}\n\t\treturn tableInformation;\n\t}\n\n\t@Override\n\tpublic boolean isCaching() {\n\t\treturn false;\n\t}\n}\n","sourceCodeStart":165,"sourceCodeEnd":193,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/DatabaseInformationImpl.java#L165-L193","documentation":"SchemaExtractionException from DatabaseInformationImpl.locateNonNullTableInformation: Hibernate needs a table's JDBC-level TableInformation to enumerate its foreign keys (locateForeignKeyInformation) or indexes (locateIndexesInformation), but locateTableInformation returned null - no table exists under that qualified name once catalog/schema defaults are applied. The mapping references a table the live database does not have.","triggerScenarios":"Calling locateForeignKeyInformation/locateIndexesInformation during SchemaUpdate or SchemaValidator passes when getTableInformation for the same qualified name is null: the table was never created, the connection resolves a different catalog/schema, or identifier case/quoting mismatches (PostgreSQL folding unquoted CamelCase to lowercase, quoted vs unquoted names, PhysicalNamingStrategy changes).","commonSituations":"Entity @Table(name = \"OrderLine\") validated against a PostgreSQL table physically named order_line; JDBC URL pointing at the wrong database or missing hibernate.default_schema; running update against an empty schema; changing the physical naming strategy between Hibernate versions so generated names no longer match.","solutions":["Verify the table exists with exact case in exactly the catalog/schema the connection resolves (SELECT ... FROM information_schema.tables).","Align the mapped name with the physical name: fix @Table(name=...) or configure a consistent PhysicalNamingStrategy (e.g. CamelCaseToUnderscoresNamingStrategy).","Set hibernate.default_schema / hibernate.default_catalog explicitly when the connection's default namespace differs from the mapped one.","Ensure the schema is created first (run migrations or SchemaExport create) before update/validate passes that resolve FK/index metadata."],"exampleFix":"// before: mapping name does not match the physical table on a case-sensitive DB\n@Entity\n@Table(name = \"OrderLine\")\npublic class OrderLine { ... }\n\n// after: match the physical table exactly (or let the naming strategy produce it)\n@Entity\n@Table(name = \"order_line\")\npublic class OrderLine { ... }","handlingStrategy":"validation","validationCode":"// Before update/validate, confirm the table resolves in live JDBC metadata (locateTableInformation returns null instead of throwing)\nDatabaseInformation dbInfo = ...; // from HibernateSchemaManagementTool extraction context\nTableInformation ti = dbInfo.locateTableInformation(\n        new QualifiedTableName(\n                Identifier.toIdentifier(catalog),\n                Identifier.toIdentifier(schema),\n                Identifier.toIdentifier(\"order_line\")));\nif (ti == null) {\n    // create the table or fix naming/schema config before proceeding\n}","typeGuard":null,"tryCatchPattern":"try {\n    schemaMigrator.doMigration(metadata, executionOptions, inclusionFilter, target);\n} catch (SchemaManagementException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not locate table information\")) {\n        // extract the qualified table name from the message, compare with the physical schema, fix naming/schema settings\n    }\n    throw e;\n}","preventionTips":["Apply one PhysicalNamingStrategy (e.g. CamelCaseToUnderscoresNamingStrategy) consistently at create time and validate time","Set hibernate.default_schema/default_catalog explicitly rather than relying on connection defaults","Run hbm2ddl validate in CI against a freshly migrated schema so drift is caught before deployment"],"tags":["hibernate","schema-management","table-not-found","schema-extraction","naming-strategy"],"backgroundTag":"table-not-found","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}