alibaba/canal · error · NullPointerException

dbMapping.targetTable

Error message

dbMapping.targetTable

What it means

Thrown by rdb MappingConfig.validate() when dbMapping.targetTable is null or empty AND mirrorDb is false. targetTable is the destination table where data is written; for non-mirror mappings it is mandatory, but mirrorDb mappings derive targets from the schema and omit it, hence the getMirrorDb() guard.

Source

Thrown at client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/config/MappingConfig.java:90

    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public AdapterMapping getMapping() {
        return dbMapping;
    }

    public void validate() {
        if (dbMapping.database == null || dbMapping.database.isEmpty()) {
            throw new NullPointerException("dbMapping.database");
        }
        if (!dbMapping.getMirrorDb() && (dbMapping.table == null || dbMapping.table.isEmpty())) {
            throw new NullPointerException("dbMapping.table");
        }
        if (!dbMapping.getMirrorDb() && (dbMapping.targetTable == null || dbMapping.targetTable.isEmpty())) {
            throw new NullPointerException("dbMapping.targetTable");
        }
    }

    public static class DbMapping implements AdapterMapping {

        private boolean             mirrorDb        = false;                 // 是否镜像库
        private String              database;                                // 数据库名或schema名
        private String              table;                                   // 表名
        private Map<String, String> targetPk        = new LinkedHashMap<>(); // 目标表主键字段
        private boolean             mapAll          = false;                 // 映射所有字段
        private String              targetDb;                                // 目标库名
        private String              targetTable;                             // 目标表名
        private Map<String, String> targetColumns;                           // 目标表字段映射

        private boolean             caseInsensitive = false;                 // 目标表不区分大小写,默认是否

        private String              etlCondition;                            // etl条件sql

View on GitHub (pinned to 87be50e876)

Solutions

  1. For a table mapping, add a non-empty 'targetTable:' under dbMapping (e.g. 'mytest2.user').
  2. If this is a whole-schema mirror, set 'mirrorDb: true' under dbMapping so targetTable/table are not required.

Example fix

# table mapping fix
# before
dbMapping:
  database: mytest
  table: user
# after
dbMapping:
  database: mytest
  table: user
  targetTable: mytest2.user
# mirror-db alternative
dbMapping:
  mirrorDb: true
  database: mytest
Defensive patterns

Strategy: validation

Validate before calling

DbMapping m = config.getDbMapping();
boolean needsTarget = m == null || !m.getMirrorDb();
if (needsTarget && (m.getTargetTable() == null || m.getTargetTable().isEmpty())) {
    throw new IllegalArgumentException(
        "rdb yml missing dbMapping.targetTable for " + fileName
        + " (or set mirrorDb:true for whole-schema sync)");
}

Prevention

When it happens

Trigger: A non-mirror rdb mapping yml's dbMapping block omits or blanks 'targetTable:', or mirrorDb is false/unset on a config meant to be a mirror.

Common situations: A table-mapping template had 'targetTable:' deleted. A mirror-schema config forgot 'mirrorDb: true' so the validator still demands a targetTable.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/4b0862994436cbe4. Report an issue: GitHub.