{"record":{"id":"a7c512d687979c00","repo":"hibernate/hibernate-orm","slug":"wrong-number-of-generated-columns","errorCode":null,"errorMessage":"wrong number of generated columns","messagePattern":"wrong number of generated columns","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/Insert.java","lineNumber":108,"sourceCode":"\n\tpublic Insert addColumn(String columnName, String valueExpression) {\n\t\tcolumns.put( columnName, valueExpression );\n\t\treturn this;\n\t}\n\n\tpublic Insert addIdentityColumn(String columnName) {\n\t\tfinal IdentityColumnSupport identityColumnSupport = dialect.getIdentityColumnSupport();\n\t\tif ( identityColumnSupport.hasIdentityInsertKeyword() ) {\n\t\t\taddColumn( columnName, identityColumnSupport.getIdentityInsertString() );\n\t\t}\n\t\treturn this;\n\t}\n\n\tpublic Insert addGeneratedColumns(String[] columnNames, OnExecutionGenerator generator) {\n\t\tif ( generator.referenceColumnsInSql( dialect ) ) {\n\t\t\tString[] columnValues = generator.getReferencedColumnValues( dialect );\n\t\t\tif ( columnNames.length != columnValues.length ) {\n\t\t\t\tthrow new MappingException(\"wrong number of generated columns\"); //TODO!\n\t\t\t}\n\t\t\tfor ( int i = 0; i < columnNames.length; i++ ) {\n\t\t\t\taddColumn( columnNames[i], columnValues[i] );\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tpublic Insert setTableName(String tableName) {\n\t\tthis.tableName = tableName;\n\t\treturn this;\n\t}\n\n\tpublic String toStatementString() {\n\t\tfinal StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 );\n\n\t\tif ( comment != null ) {\n\t\t\tbuf.append( \"/* \" ).append( Dialect.escapeComment( comment ) ).append( \" */ \" );","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/Insert.java#L90-L126","documentation":"When an INSERT includes columns generated on execution, Hibernate asks the OnExecutionGenerator whether it references columns in SQL (referenceColumnsInSql(dialect)); if true, getReferencedColumnValues(dialect) must return exactly one value per generated column. A length mismatch between the column-name array and the value array throws MappingException(\"wrong number of generated columns\") — the generator's contract is broken.","triggerScenarios":"A custom OnExecutionGenerator (used with @Generated / generated-on-insert mappings) whose getReferencedColumnValues returns a wrong-length array — e.g., returning a single default keyword for an entity with two generated columns; dialect-conditional arrays that forget a dialect branch.","commonSituations":"Writing custom generators for DB defaults, trigger-populated columns, or tenant placeholders; porting generators from the old GeneratedValue/BeforeExecutionGenerator contracts where the array rules differ.","solutions":["Return an array whose length equals the number of generated columns passed in — one value per column","If the database generates the values itself (DEFAULT/identity), return referenceColumnsInSql() == false and an empty array instead","Unit-test the generator against every dialect it can run under, asserting columnNames.length == columnValues.length"],"exampleFix":"// before\npublic class TriggerDefaultGenerator implements OnExecutionGenerator {\n    public boolean referenceColumnsInSql(Dialect d) { return true; }\n    public String[] getReferencedColumnValues(Dialect d) {\n        return new String[] { \"default\" }; // entity has TWO generated columns -> mismatch\n    }\n}\n\n// after\npublic boolean referenceColumnsInSql(Dialect d) { return false; } // DB generates values\npublic String[] getReferencedColumnValues(Dialect d) { return ArrayHelper.EMPTY_STRING_ARRAY; }","handlingStrategy":"validation","validationCode":"// put this in the generator itself or its unit test\nassert columnNames.length == getReferencedColumnValues(dialect).length\n        || !referenceColumnsInSql(dialect) : \"generated column/value count mismatch\";","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When the DB generates values, return referenceColumnsInSql() == false and an empty array","When referencing SQL values, always return exactly one value per generated column","Unit-test custom OnExecutionGenerator implementations per dialect and per column count"],"tags":["mapping","generators","insert","sql-generation"],"backgroundTag":"mapping-misconfiguration","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}