{"record":{"id":"dcaa08e97384fe73","repo":"mybatis/mybatis-3","slug":"two-different-properties-are-mapped-to-the-same-re","errorCode":null,"errorMessage":"Two different properties are mapped to the same resultSet","messagePattern":"Two different properties are mapped to the same resultSet","errorType":"exception","errorClass":"ExecutorException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java","lineNumber":719,"sourceCode":"      }\n    }\n  }\n\n  private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject, ResultMapping parentMapping)\n      throws SQLException {\n    CacheKey cacheKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(),\n        parentMapping.getColumn());\n    PendingRelation deferLoad = new PendingRelation();\n    deferLoad.metaObject = metaResultObject;\n    deferLoad.propertyMapping = parentMapping;\n    List<PendingRelation> relations = pendingRelations.computeIfAbsent(cacheKey, k -> new ArrayList<>());\n    // issue #255\n    relations.add(deferLoad);\n    ResultMapping previous = nextResultMaps.get(parentMapping.getResultSet());\n    if (previous == null) {\n      nextResultMaps.put(parentMapping.getResultSet(), parentMapping);\n    } else if (!previous.equals(parentMapping)) {\n      throw new ExecutorException(\"Two different properties are mapped to the same resultSet\");\n    }\n  }\n\n  private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultMapping, String names, String columns)\n      throws SQLException {\n    CacheKey cacheKey = new CacheKey();\n    cacheKey.update(resultMapping);\n    if (columns != null && names != null) {\n      String[] columnsArray = columns.split(\",\");\n      String[] namesArray = names.split(\",\");\n      for (int i = 0; i < columnsArray.length; i++) {\n        Object value = rs.getString(columnsArray[i]);\n        if (value != null) {\n          cacheKey.update(namesArray[i]);\n          cacheKey.update(value);\n        }\n      }\n    }","sourceCodeStart":701,"sourceCodeEnd":737,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java#L701-L737","documentation":"In multi-ResultSet statements (stored procedures with resultSet='...' mappings), each named ResultSet may drive at most one property mapping. addPendingChildRelation tracks the ResultMapping per resultSet name in nextResultMaps; when a second, different ResultMapping claims the same resultSet name, this ExecutorException is thrown.","triggerScenarios":"Two @Result/column mappings in one statement (or two statements feeding one resultMap) declare the same resultSet=\"foo\" but map to different properties — e.g. @Result(property=\"a\", resultSet=\"rs2\") and @Result(property=\"b\", resultSet=\"rs2\") with differing columns.","commonSituations":"Copy-pasting @Result annotations for multiple children of a stored-procedure result and forgetting to give each child its own resultSet name; refactoring a stored proc to merge result sets without updating the mappings.","solutions":["Give each child collection its own ResultSet name in the mapping so one name maps one property","If two properties truly share one result set, map one collection and derive the second property from it in Java code","Alter the stored procedure to emit separate result sets per collection"],"exampleFix":"// before\n@Results({\n  @Result(property=\"items\", column=\"order_id\", many=@Many(select=\"getItems\"), resultSet=\"rs2\"),\n  @Result(property=\"notes\", column=\"order_id\", many=@Many(select=\"getNotes\"), resultSet=\"rs2\")\n})\n// after: separate result sets\n@Results({\n  @Result(property=\"items\", column=\"order_id\", many=@Many(select=\"getItems\"), resultSet=\"rs2\"),\n  @Result(property=\"notes\", column=\"order_id\", many=@Many(select=\"getNotes\"), resultSet=\"rs3\")\n})","handlingStrategy":"validation","validationCode":"// Validate at startup: each resultSet name maps at most one property per statement\nfor (String id : cfg.getMappedStatementNames()) {\n  Set<String> seen = new HashSet<>();\n  for (ResultMap rm : cfg.getMappedStatement(id).getResultMaps()) {\n    for (ResultMapping m : rm.getResultMappings()) {\n      if (m.getResultSet() != null && !seen.add(m.getResultSet() + '|' + m.getProperty())) {\n        // detect duplicates by resultSet name below instead\n      }\n    }\n  }\n}\nSet<String> rsNames = new HashSet<>();\nfor (ResultMapping m : cfg.getResultMap(\"orderMap\").getResultMappings()) {\n  if (m.getResultSet() != null && !rsNames.add(m.getResultSet())) throw new IllegalStateException(\"Duplicate resultSet mapping: \" + m.getResultSet());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One resultSet name per child property in multi-resultset mappings","Review stored-proc signature changes against mapping annotations","Keep multi-resultset mappings in one reviewable place"],"tags":["mybatis","multiple-resultsets","stored-procedure","mapping"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}