mybatis/mybatis-3 · error · ExecutorException
Cursor results cannot be mapped to multiple resultMaps
Error message
Cursor results cannot be mapped to multiple resultMaps
What it means
DefaultResultSetHandler.handleCursorResultSets only supports a single ResultSet mapping: when a statement run through selectCursor()/Cursor return has more than one resultMap declared (multiple result sets), it throws this ExecutorException because a Cursor is a streaming single-result API.
Source
Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:259
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}
@Override
public <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling cursor results").object(mappedStatement.getId());
ResultSetWrapper rsw = getFirstResultSet(stmt);
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
if (resultMapCount != 1) {
throw new ExecutorException("Cursor results cannot be mapped to multiple resultMaps");
}
ResultMap resultMap = resultMaps.get(0);
return new DefaultCursor<>(this, resultMap, rsw, rowBounds);
}
private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
ResultSet rs = null;
SQLException e1 = null;
try {
rs = stmt.getResultSet();
} catch (SQLException e) {
// Oracle throws ORA-17283 for implicit cursor
e1 = e;
}
try {View on GitHub (pinned to 008069adb1)
Solutions
- Use selectList/List-returning mapper methods for statements that return multiple result maps
- Split the stored procedure or statement so each Cursor maps exactly one result set
- If you only need the first result set, define a dedicated statement with a single resultMap for it
Example fix
// before: statement maps 2 resultSets
Cursor<Order> c = session.selectCursor("sel.ordersWithItems"); // throws
// after: dedicated single-resultMap statement
Cursor<Order> c = session.selectCursor("sel.ordersOnly");
List<Item> items = session.selectList("sel.itemsOnly"); Defensive patterns
Strategy: validation
Validate before calling
// Only use Cursor when the statement maps exactly one result set
MappedStatement ms = session.getConfiguration().getMappedStatement("sel.ordersWithItems");
if (ms.getResultMaps().size() != 1) { throw new UnsupportedOperationException("Use selectList for multi-resultMap statements"); }
try (Cursor<Order> c = session.selectCursor("sel.ordersWithItems")) { ... } Try / catch
try (Cursor<Order> c = session.selectCursor(stmt)) { ... } catch (ExecutorException e) { if (e.getMessage().contains("multiple resultMaps")) { fallback to session.selectList(stmt); } else throw e; } Prevention
- Reserve Cursor APIs for single-result-set statements
- Keep a project convention: streaming consumers get dedicated single-resultMap statements
- Review multi-resultset stored procs before switching consumers to Cursor
When it happens
Trigger: sqlSession.selectCursor(...) (or a mapper method returning Cursor<T>) on a mapped statement whose resultMaps list size != 1 — e.g. two <resultSet> mappings in a stored-procedure mapper, or resultType plus an extra resultMap after refactoring.
Common situations: Converting a selectList call backed by a multi-resultset stored procedure to selectCursor for streaming; annotating a mapper method with @ResultMap lists yielding multiple maps; copy-pasting a multi-resultset statement and switching its consumer to Cursor.
Related errors
- Cannot open more than one iterator on a Cursor
- Cannot remove element from Cursor
- Could not find a parent resultMap with id '{extend}'
- Could not find result map '{resultMapName}' referenced from
- Error in result map '{resultMapId}'. Failed to find a constr
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/3e5175d0739e211a.
Report an issue: GitHub.