mybatis/mybatis-3 · error · ExecutorException
Two different properties are mapped to the same resultSet
Error message
Two different properties are mapped to the same resultSet
What it means
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.
Source
Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:719
}
}
}
private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject, ResultMapping parentMapping)
throws SQLException {
CacheKey cacheKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(),
parentMapping.getColumn());
PendingRelation deferLoad = new PendingRelation();
deferLoad.metaObject = metaResultObject;
deferLoad.propertyMapping = parentMapping;
List<PendingRelation> relations = pendingRelations.computeIfAbsent(cacheKey, k -> new ArrayList<>());
// issue #255
relations.add(deferLoad);
ResultMapping previous = nextResultMaps.get(parentMapping.getResultSet());
if (previous == null) {
nextResultMaps.put(parentMapping.getResultSet(), parentMapping);
} else if (!previous.equals(parentMapping)) {
throw new ExecutorException("Two different properties are mapped to the same resultSet");
}
}
private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultMapping, String names, String columns)
throws SQLException {
CacheKey cacheKey = new CacheKey();
cacheKey.update(resultMapping);
if (columns != null && names != null) {
String[] columnsArray = columns.split(",");
String[] namesArray = names.split(",");
for (int i = 0; i < columnsArray.length; i++) {
Object value = rs.getString(columnsArray[i]);
if (value != null) {
cacheKey.update(namesArray[i]);
cacheKey.update(value);
}
}
}View on GitHub (pinned to 008069adb1)
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
Example fix
// before
@Results({
@Result(property="items", column="order_id", many=@Many(select="getItems"), resultSet="rs2"),
@Result(property="notes", column="order_id", many=@Many(select="getNotes"), resultSet="rs2")
})
// after: separate result sets
@Results({
@Result(property="items", column="order_id", many=@Many(select="getItems"), resultSet="rs2"),
@Result(property="notes", column="order_id", many=@Many(select="getNotes"), resultSet="rs3")
}) Defensive patterns
Strategy: validation
Validate before calling
// Validate at startup: each resultSet name maps at most one property per statement
for (String id : cfg.getMappedStatementNames()) {
Set<String> seen = new HashSet<>();
for (ResultMap rm : cfg.getMappedStatement(id).getResultMaps()) {
for (ResultMapping m : rm.getResultMappings()) {
if (m.getResultSet() != null && !seen.add(m.getResultSet() + '|' + m.getProperty())) {
// detect duplicates by resultSet name below instead
}
}
}
}
Set<String> rsNames = new HashSet<>();
for (ResultMapping m : cfg.getResultMap("orderMap").getResultMappings()) {
if (m.getResultSet() != null && !rsNames.add(m.getResultSet())) throw new IllegalStateException("Duplicate resultSet mapping: " + m.getResultSet());
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- There should be the same number of columns and foreignColumn
- Error resolving ParameterMode. Cause: {cause}
- Ambiguous collection type for property '{property}'. You mus
- Caching stored procedures with OUT params is not supported.
- No type handler found for '" + javaType + "' and JDBC type '
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/dcaa08e97384fe73.
Report an issue: GitHub.