{"record":{"id":"4f0d992bcaa86b01","repo":"hibernate/hibernate-orm","slug":"subclass-key-mapping-has-wrong-number-of-columns","errorCode":null,"errorMessage":"subclass key mapping has wrong number of columns: \" + getEntityName() + \" type: \" + key.getType().getName()","messagePattern":"subclass key mapping has wrong number of columns: \" \\+ getEntityName\\(\\) \\+ \" type: \" \\+ key\\.getType\\(\\)\\.getName\\(\\)","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java","lineNumber":47,"sourceCode":"\t}\n\n\tpublic void setTable(Table table) {\n\t\tthis.table = table;\n\t\tgetSuperclass().addSubclassTable( table );\n\t}\n\n\tpublic KeyValue getKey() {\n\t\treturn key;\n\t}\n\n\tpublic void setKey(KeyValue key) {\n\t\tthis.key = key;\n\t}\n\n\tpublic void validate(Metadata mapping) throws MappingException {\n\t\tsuper.validate( mapping );\n\t\tif ( key != null && !key.isValid( mapping ) ) {\n\t\t\tthrow new MappingException(\n\t\t\t\t\t\"subclass key mapping has wrong number of columns: \" +\n\t\t\t\t\tgetEntityName() +\n\t\t\t\t\t\" type: \" +\n\t\t\t\t\tkey.getType().getName()\n\t\t\t\t);\n\t\t}\n\t}\n\n\tpublic Object accept(PersistentClassVisitor mv) {\n\t\treturn mv.accept(this);\n\t}\n}\n","sourceCodeStart":29,"sourceCodeEnd":60,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/JoinedSubclass.java#L29-L60","documentation":"JoinedSubclass#validate checks the shared key of a JOINED inheritance subclass and throws when the key Value's column span does not match its type. With JOINED inheritance the subclass table's primary/foreign key must align exactly with the parent's key mapping.","triggerScenarios":"Parent uses a composite @EmbeddedId/@IdClass but the subclass lacks @PrimaryKeyJoinColumns covering all key columns; a PK column was added to the parent hierarchy without updating subclass join columns; an hbm subclass <key> lists fewer <column> entries than the parent key.","commonSituations":"Composite keys introduced into an existing JOINED hierarchy; refactoring from single-column to composite ids; hand-written hbm subclass joins.","solutions":["Add @PrimaryKeyJoinColumns to the subclass with one @PrimaryKeyJoinColumn per parent PK column (explicit referencedColumnName).","If the parent key changed, update all JOINED subclasses' key mappings in the same commit.","In hbm, list all key columns inside the subclass <key> element."],"exampleFix":"// before - composite parent PK, subclass key incomplete\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\npublic class Parent { @EmbeddedId CompId id; }\n\n@Entity\npublic class Child extends Parent { }\n\n// after\n@Entity\n@PrimaryKeyJoinColumns({\n    @PrimaryKeyJoinColumn(name = \"a\", referencedColumnName = \"a\"),\n    @PrimaryKeyJoinColumn(name = \"b\", referencedColumnName = \"b\")\n})\npublic class Child extends Parent { }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    metadata = sources.buildMetadata();\n} catch (MappingException e) {\n    // message names the subclass entity + key type - compare its join\n    // column list with the parent's PK columns\n    throw e;\n}","preventionTips":["For composite ids always declare @PrimaryKeyJoinColumns explicitly on every JOINED subclass.","When the parent key shape changes, update all JOINED subclasses in the same commit.","Validate full inheritance hierarchies with a metadata build test."],"tags":["hibernate","orm","mapping","inheritance","joined","primary-key"],"backgroundTag":"joined-inheritance-key-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}