{"record":{"id":"efe2eddbcf261c78","repo":"mybatis/mybatis-3","slug":"if-selectkey-has-key-columns-the-number-must-matc","errorCode":null,"errorMessage":"If SelectKey has key columns, the number must match the number of key properties.","messagePattern":"If SelectKey has key columns, the number must match the number of key properties\\.","errorType":"exception","errorClass":"ExecutorException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java","lineNumber":105,"sourceCode":"      }\n    } catch (ExecutorException e) {\n      throw e;\n    } catch (Exception e) {\n      throw new ExecutorException(\"Error selecting key or setting result to parameter object. Cause: \" + e, e);\n    }\n  }\n\n  private void handleMultipleProperties(String[] keyProperties, MetaObject metaParam, MetaObject metaResult) {\n    String[] keyColumns = keyStatement.getKeyColumns();\n\n    if (keyColumns == null || keyColumns.length == 0) {\n      // no key columns specified, just use the property names\n      for (String keyProperty : keyProperties) {\n        setValue(metaParam, keyProperty, metaResult.getValue(keyProperty));\n      }\n    } else {\n      if (keyColumns.length != keyProperties.length) {\n        throw new ExecutorException(\n            \"If SelectKey has key columns, the number must match the number of key properties.\");\n      }\n      for (int i = 0; i < keyProperties.length; i++) {\n        setValue(metaParam, keyProperties[i], metaResult.getValue(keyColumns[i]));\n      }\n    }\n  }\n\n  private void setValue(MetaObject metaParam, String property, Object value) {\n    if (!metaParam.hasSetter(property)) {\n      throw new ExecutorException(\"No setter found for the keyProperty '\" + property + \"' in \"\n          + metaParam.getOriginalObject().getClass().getName() + \".\");\n    }\n    metaParam.setValue(property, value);\n  }\n}\n","sourceCodeStart":87,"sourceCodeEnd":122,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java#L87-L122","documentation":"When a <selectKey> declares both keyProperty (possibly multiple) and keyColumn, handleMultipleProperties pairs them by index. If the number of key columns does not equal the number of key properties, the pairing is ambiguous, so MyBatis throws this ExecutorException before assigning anything.","triggerScenarios":"keyProperty=\"id,name\" with keyColumn=\"id\" (or vice versa); composite-key selects where columns and properties are listed with different lengths; stray comma or missing entry in one of the two attributes.","commonSituations":"Adding a second key property and forgetting to add its column, or renaming and dropping one side only.","solutions":["Count entries: keyColumn must have exactly as many comma-separated names as keyProperty","Order both lists identically since pairing is positional","If the select returns a single value, drop keyColumn entirely and keep one keyProperty"],"exampleFix":"<!-- before -->\n<selectKey keyProperty=\"id,name\" keyColumn=\"id\" ...>\n\n<!-- after -->\n<selectKey keyProperty=\"id,name\" keyColumn=\"id,name\" ...>","handlingStrategy":"validation","validationCode":"// Startup config lint: keyColumn count must equal keyProperty count\nif (keyColumns != null && keyColumns.length != keyProperties.length) {\n  throw new IllegalStateException(\"<selectKey> keyProperty/keyColumn count mismatch\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When editing composite keys, update keyProperty and keyColumn together","Keep both lists in identical positional order"],"tags":["selectkey","keycolumn","configuration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}