{"record":{"id":"17565a80579e36b1","repo":"alibaba/canal","slug":"rowkey-rowkey","errorCode":null,"errorMessage":"已配置了复合主键作为RowKey，无需再指定RowKey列","messagePattern":"已配置了复合主键作为RowKey，无需再指定RowKey列","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/config/MappingConfig.java","lineNumber":83,"sourceCode":"    public AdapterMapping getMapping() {\n        return hbaseMapping;\n    }\n\n    public void validate() {\n        if (hbaseMapping.database == null || hbaseMapping.database.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.database\");\n        }\n        if (hbaseMapping.table == null || hbaseMapping.table.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.table\");\n        }\n        if (hbaseMapping.hbaseTable == null || hbaseMapping.hbaseTable.isEmpty()) {\n            throw new NullPointerException(\"hbaseMapping.hbaseTable\");\n        }\n        if (hbaseMapping.mode == null) {\n            throw new NullPointerException(\"hbaseMapping.mode\");\n        }\n        if (hbaseMapping.rowKey != null && hbaseMapping.rowKeyColumn != null) {\n            throw new RuntimeException(\"已配置了复合主键作为RowKey，无需再指定RowKey列\");\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        MappingConfig config = (MappingConfig) o;\n\n        return hbaseMapping != null ? hbaseMapping.equals(config.hbaseMapping) : config.hbaseMapping == null;\n    }\n\n    @Override\n    public int hashCode() {\n        return hbaseMapping != null ? hbaseMapping.hashCode() : 0;\n    }\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/config/MappingConfig.java#L65-L101","documentation":"MappingConfig.validate() rejects a mapping that configures BOTH a composite rowKey (hbaseMapping.rowKey, a comma-separated column list) AND a single rowKeyColumn (a column flagged as ROWKEY in the columns map). These are two mutually exclusive rowKey strategies; specifying both is a configuration contradiction.","triggerScenarios":"HBase mapping YAML that sets 'hbaseMapping.rowKey: col1,col2' AND also has a column whose value starts with 'ROWKEY' (which auto-populates rowKeyColumn).","commonSituations":"Authoring a mapping and using both the composite-key and single-ROWKEY-column syntax by mistake; merging two config snippets.","solutions":["Choose ONE rowKey strategy: either set 'rowKey: c1,c2' for a composite key, OR mark a single column value as 'ROWKEY' / 'ROWKEYLEN:n', but not both.","Remove the 'rowKey:' line if you intend the single-column ROWKEY mapping.","Remove the 'ROWKEY' marker from any column if you intend the composite 'rowKey:' mapping.","Re-validate the YAML after the edit."],"exampleFix":"# before (both set)\nhbaseMapping:\n  rowKey: id,ts\n  columns:\n    id: ROWKEY\n\n# after (composite only)\nhbaseMapping:\n  rowKey: id,ts\n  columns:\n    id: CF:id","handlingStrategy":"validation","validationCode":"MappingConfig.HbaseMapping m = config.getHbaseMapping();\nboolean hasCompositeKey = m.getRowKey() != null;\nboolean hasRowKeyColumn = m.getRowKeyColumn() != null;\nif (hasCompositeKey && hasRowKeyColumn) {\n    throw new IllegalStateException(\"Specify either rowKey (composite) or a single ROWKEY column, not both\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    config.validate();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"RowKey\")) {\n        logger.error(\"Remove either rowKey or the ROWKEY column marker\");\n    }\n    throw e;\n}","preventionTips":["Pick exactly one rowKey strategy per mapping.","Review the columns map for any value starting with 'ROWKEY' when 'rowKey:' is also set.","Lint the mapping in CI."],"tags":["hbase-adapter","config","validation","rowkey"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}