MyCATApache/Mycat-Server · error · ConfigException
table duplicated!
Error message
table ${table.getName()} duplicated! What it means
Thrown by XMLSchemaLoader's child-table processing (processChildTables, called recursively from the constructor) when a child <table> in a parent/child (ER) sharding setup has the same name as a table already registered. Child tables are also keyed by name in the tables map, so duplicates are rejected at load.
Solutions
- Give the childTable a unique name distinct from all other tables and child tables
- Remove the duplicate childTable element from schema.xml
- Verify the parent/child table hierarchy has unique names at every level
Example fix
// before (schema.xml) <childTable name="orders" joinKey="cid" parentKey="id" /> // after <childTable name="order_items" joinKey="cid" parentKey="id" />
Defensive patterns
Strategy: validation
Validate before calling
// collect parent + childTable names and ensure uniqueness before load
Set<String> names = new HashSet<>();
for (Element t : schemaTables("schema.xml")) {
addAllTableNames(names, t); // includes nested <childTable> recursively
}
if (names.size() != totalCount) throw new IllegalStateException("Duplicate child table name"); Try / catch
try {
configLoader.load();
} catch (ConfigException e) {
if (e.getMessage().contains("duplicated!")) {
log.error("Child table name collides with an existing table/childTable in schema.xml", e);
}
throw e;
} Prevention
- Name child tables with distinct suffixes (e.g. order_item vs order) to avoid collisions
- Walk the childTable tree after edits to confirm unique names at each level
- Never reuse a parent's name for a child table
When it happens
Trigger: A nested <childTable name="..."> (or recursive child-of-child) whose name equals a table already present in the tables map, including a child table colliding with its parent or sibling.
Common situations: Copy-pasted childTable blocks with the same name; child table name accidentally matching a normal table; deep sub-table recursion reusing names.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- table duplicated!
- dataNode duplicated!
- ConfigException wrapping cause (no message)
- table rule duplicated!
- rule function duplicated!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/ea47558130c825b1.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:550
autoIncrement = Boolean.parseBoolean(childTbElement.getAttribute("autoIncrement"));
}
boolean needAddLimit = true;
if (childTbElement.hasAttribute("needAddLimit")) {
needAddLimit = Boolean.parseBoolean(childTbElement.getAttribute("needAddLimit"));
}
String subTables = childTbElement.getAttribute("subTables");
//子表join键,和对应的parent的键,父子表通过这个关联
String joinKey = childTbElement.getAttribute("joinKey").toUpperCase();
String parentKey = childTbElement.getAttribute("parentKey").toUpperCase();
TableConfig table = new TableConfig(cdTbName, primaryKey,
autoIncrement, needAddLimit,
TableConfig.TYPE_GLOBAL_DEFAULT, dataNodes,
getDbType(dataNodes), null, false, parentTable, true,
joinKey, parentKey, subTables, false);
if (tables.containsKey(table.getName())) {
throw new ConfigException("table " + table.getName() + " duplicated!");
}
tables.put(table.getName(), table);
//对于子表的子表,递归处理
processChildTables(tables, table, dataNodes, childTbElement);
}
}
private void checkDataNodeExists(Collection<String> nodes) {
if (nodes == null || nodes.size() < 1) {
return;
}
for (String node : nodes) {
if (!dataNodes.containsKey(node)) {
throw new ConfigException("dataNode '" + node + "' is not found!");
}
}
}
View on GitHub (pinned to 65f8d8beb7)