mybatis/mybatis-3 · error · BindingException
method {name} needs either a @ResultMap annotation, a @Resul
Error message
method {name} needs either a @ResultMap annotation, a @ResultType annotation, or a resultType attribute in XML so a ResultHandler can be used as a parameter. What it means
executeWithResultHandler() requires that MyBatis knows the row type before streaming rows into a ResultHandler. For non-CALLABLE statements, if the first result map's type is void.class (the default placeholder), MyBatis cannot create result objects, so it demands an explicit result type declaration.
Source
Thrown at src/main/java/org/apache/ibatis/binding/MapperMethod.java:127
result = null;
} else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
result = rowCount;
} else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
result = (long) rowCount;
} else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
result = rowCount > 0;
} else {
throw new BindingException(
"Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
}
return result;
}
private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {
MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
if (!StatementType.CALLABLE.equals(ms.getStatementType())
&& void.class.equals(ms.getResultMaps().get(0).getType())) {
throw new BindingException(
"method " + command.getName() + " needs either a @ResultMap annotation, a @ResultType annotation,"
+ " or a resultType attribute in XML so a ResultHandler can be used as a parameter.");
}
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
} else {
sqlSession.select(command.getName(), param, method.extractResultHandler(args));
}
}
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
List<E> result;
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
result = sqlSession.selectList(command.getName(), param, rowBounds);View on GitHub (pinned to 008069adb1)
Solutions
- Add resultType="com.example.X" (or a resultMap attribute) to the <select> element
- Or annotate the mapper method with @ResultMap("...id...") or @ResultType(X.class)
Example fix
<!-- before --> <select id="processAll">SELECT * FROM users</select> <!-- after --> <select id="processAll" resultType="com.example.User">SELECT * FROM users</select>
Defensive patterns
Strategy: validation
Validate before calling
MappedStatement ms = configuration.getMappedStatement("com.example.UserMapper.processAll");
Class<?> rowType = ms.getResultMaps().get(0).getType();
if (rowType == void.class) {
throw new IllegalStateException("Add resultType/resultMap before using ResultHandler");
} Prevention
- Always pair ResultHandler mapper methods with an explicit resultType or @ResultType
- Add a build-time check that every <select> declares resultType or resultMap
When it happens
Trigger: Declaring 'void processAll(ResultHandler<X> handler)' in a mapper interface where the XML <select> has no resultType/resultMap attribute and no @ResultMap/@ResultType annotation is present; stored procedures (CALLABLE) are exempt because OUT params carry types.
Common situations: Streaming large result sets with ResultHandler and forgetting resultType; annotation-based mappers using @Select without @ResultType.
Related errors
- {methodName} cannot have multiple {paramType} parameters
- Unknown execution method for: {name}
- Mapper method '{name}' attempted to return null from a metho
- Mapper method '{name}' has an unsupported return type: {retu
- Parameter '{key}' not found. Available parameters are {keySe
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/8ec7713136928483.
Report an issue: GitHub.