{"record":{"id":"1635bd81fe288f60","repo":"MyCATApache/Mycat-Server","slug":"joinkey-not-provided","errorCode":null,"errorMessage":"joinKey not provided :","messagePattern":"joinKey not provided :","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java","lineNumber":128,"sourceCode":"\t/**\n\t * 是否为批量插入：insert into ...values (),()...或 insert into ...select.....\n\t * @param insertStmt\n\t * @return\n\t */\n\tprivate boolean isMultiInsert(MySqlInsertStatement insertStmt) {\n\t\treturn (insertStmt.getValuesList() != null && insertStmt.getValuesList().size() > 1) || insertStmt.getQuery() != null;\n\t}\n\t\n\tprivate RouteResultset parserChildTable(SchemaConfig schema, RouteResultset rrs,\n\t\t\tString tableName, MySqlInsertStatement insertStmt) throws SQLNonTransientException {\n\t\tTableConfig tc = schema.getTables().get(tableName);\n\t\t\n\t\tString joinKey = tc.getJoinKey();\n\t\tint joinKeyIndex = getJoinKeyIndex(insertStmt.getColumns(), joinKey);\n\t\tif(joinKeyIndex == -1) {\n\t\t\tString inf = \"joinKey not provided :\" + tc.getJoinKey()+ \",\" + insertStmt;\n\t\t\tLOGGER.warn(inf);\n\t\t\tthrow new SQLNonTransientException(inf);\n\t\t}\n\t\tif(isMultiInsert(insertStmt)) {\n\t\t\tString msg = \"ChildTable multi insert not provided\" ;\n\t\t\tLOGGER.warn(msg);\n\t\t\tthrow new SQLNonTransientException(msg);\n\t\t}\n\t\t\n\t\tString joinKeyVal = insertStmt.getValues().getValues().get(joinKeyIndex).toString();\n\n\t\t\n\t\tString sql = insertStmt.toString();\n\t\t\n\t\t// try to route by ER parent partion key\n\t\tRouteResultset theRrs = RouterUtil.routeByERParentKey(null,schema, ServerParse.INSERT,sql, rrs, tc,joinKeyVal);\n\t\tif (theRrs != null) {\n\t\t\trrs.setFinishedRoute(true);\n\t\t\treturn theRrs;\n\t\t}","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java#L110-L146","documentation":"When inserting into an ER (child) table, Mycat locates the parent row's storage node via the joinKey. getJoinKeyIndex scans the INSERT's column list for the joinKey; if the join key column is absent (index -1), routing is impossible and a SQLNonTransientException is thrown naming the joinKey and the statement.","triggerScenarios":"INSERT into a childTable (childTable=\"...\" joinKey=\"...\") whose column list does not include the configured joinKey column, e.g. INSERT INTO order_items (item_id, qty) VALUES (...) where joinKey is order_id.","commonSituations":"Child-table inserts that omit the foreign-key column; joinKey in schema.xml misspelled or different case than the SQL column; ORMs doing partial-column inserts.","solutions":["Include the joinKey column in the INSERT column list with the parent's key value.","Verify the joinKey attribute in schema.xml exactly matches (uppercased) the column name used in the SQL.","If the row genuinely has no parent link, define the table as a normal sharded table instead of a childTable."],"exampleFix":"// before\nINSERT INTO order_items (item_id, qty) VALUES (9, 2);\n// after (joinKey = order_id)\nINSERT INTO order_items (item_id, order_id, qty) VALUES (9, 1001, 2);","handlingStrategy":"validation","validationCode":"// Check the joinKey column is present before child-table insert\nfunction validateChildInsert(columns, joinKey) {\n  if (!columns.map(c => c.toUpperCase()).includes(joinKey.toUpperCase())) {\n    throw new Error(\"child-table insert must include joinKey column: \" + joinKey);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify joinKey in schema.xml matches the real child-table foreign-key column name.","Include the join key in every child-table INSERT, including ORM defaults."],"tags":["insert","child-table","join-key"],"backgroundTag":"missing-required-argument","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}