{"record":{"id":"d1ca1988ec04d1e3","repo":"hibernate/hibernate-orm","slug":"couldn-t-find-table-reference-d1ca19","errorCode":null,"errorMessage":"Couldn't find table reference","messagePattern":"Couldn't find table reference","errorType":"exception","errorClass":"UnknownTableReferenceException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java","lineNumber":421,"sourceCode":"\t\treturn tableName;\n\t}\n\n\t@Override\n\tprotected boolean isIdentifierTable(String tableExpression) {\n\t\treturn tableExpression.equals( getRootTableName() );\n\t}\n\n\t@Override\n\tpublic boolean hasMultipleTables() {\n\t\t// This could also just be true all the time...\n\t\treturn isAbstract() || hasSubclasses();\n\t}\n\n\t@Override\n\tpublic void pruneForSubclasses(TableGroup tableGroup, Map<String, EntityNameUse> entityNameUses) {\n\t\tfinal var tableReference = (NamedTableReference) tableGroup.getTableReference( getRootTableName() );\n\t\tif ( tableReference == null ) {\n\t\t\tthrow new UnknownTableReferenceException( getRootTableName(), \"Couldn't find table reference\" );\n\t\t}\n\t\ttableReference.setPrunedTableExpression( generateSubquery(\n\t\t\t\tentityNameUses,\n\t\t\t\ttableReference.getTableExpression()\n\t\t) );\n\t}\n\n\t@Override\n\tpublic void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {\n\t\tfor ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {\n\t\t\tfinal String tableName = constraintOrderedTableNames[i];\n\t\t\tfinal int tablePosition = i;\n\t\t\tconsumer.consume(\n\t\t\t\t\ttableName,\n\t\t\t\t\t() -> columnConsumer -> columnConsumer.accept(\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tconstraintOrderedKeyColumnNames[tablePosition],\n\t\t\t\t\t\t\tgetIdentifierMapping()::getJdbcMapping","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java#L403-L439","documentation":"For TABLE_PER_CLASS hierarchies, UnionSubclassEntityPersister.pruneForSubclasses replaces the root table reference with a generated subquery so only selected concrete tables are queried. It requires the incoming TableGroup to hold a reference to the root table; UnknownTableReferenceException('Couldn't find table reference') means the TableGroup was built without it, typically because a query path reused or built a table group for a subtype only.","triggerScenarios":"Polymorphic criteria/HQL with treat() against a TABLE_PER_CLASS hierarchy; loading through @Polymorphic interface references; fetch composition or entity-graph paths that construct subtype table groups for union persisters; known Hibernate defect paths in union-subclass pruning.","commonSituations":"treat(as: SubType) in HQL over union-subclass mappings; entity graphs or join fetches on TABLE_PER_CLASS hierarchies; upgrading Hibernate versions where pruning semantics changed.","solutions":["Upgrade Hibernate - union-subclass pruning has had several fixes across 6.x/7.x","Avoid treat() on TABLE_PER_CLASS hierarchies; select the concrete subtype directly instead","Query the root entity with restrictions on root columns rather than treating to a subtype","Build a minimal reproducer (query + mapping) and report it to Hibernate (HHH) if it fails on the latest version"],"exampleFix":"// before: treat() over a TABLE_PER_CLASS hierarchy\nList<Vehicle> cars = session.createQuery(\n    \"select v from Vehicle v treat(v as Car c) where c.doorCount = :d\", Vehicle.class)\n    .getResultList();\n\n// after: query the concrete subtype directly\nList<Car> cars = session.createQuery(\n    \"from Car c where c.doorCount = :d\", Car.class)\n    .getResultList();","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { results = query.getResultList(); } catch (UnknownTableReferenceException e) { /* union-subclass pruning failed: re-run the query against the concrete subtype */ }","preventionTips":["Query concrete subtypes directly instead of treat() over TABLE_PER_CLASS hierarchies","Keep Hibernate patched - union pruning has a fix history","Cover polymorphic queries over union hierarchies with regression tests"],"tags":["hibernate","orm","table-per-class","union-subclass","treat","unknown-table-reference"],"backgroundTag":"unknown-table-reference","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}