mybatis/mybatis-3 · error · ExecutorException

A query was run and no Result Maps were found for the Mapped

Error message

A query was run and no Result Maps were found for the Mapped Statement '" + mappedStatement.getId() + "'. 'resultType' or 'resultMap' must be specified when there is no corresponding method."

What it means

validateResultMapsCount fires when a statement produced a ResultSet but the MappedStatement declares zero result maps. Every query statement must tell MyBatis how to map rows, either via resultType or resultMap; without one there is no way to materialize rows.

Source

Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:334

  }

  private void closeResultSet(ResultSet rs) {
    try {
      if (rs != null) {
        rs.close();
      }
    } catch (SQLException e) {
      // ignore
    }
  }

  private void cleanUpAfterHandlingResultSet() {
    nestedResultObjects.clear();
  }

  private void validateResultMapsCount(ResultSetWrapper rsw, int resultMapCount) {
    if (rsw != null && resultMapCount < 1) {
      throw new ExecutorException(
          "A query was run and no Result Maps were found for the Mapped Statement '" + mappedStatement.getId()
              + "'. 'resultType' or 'resultMap' must be specified when there is no corresponding method.");
    }
  }

  private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults,
      ResultMapping parentMapping) throws SQLException {
    try {
      if (parentMapping != null) {
        handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
      } else if (resultHandler == null) {
        DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
        handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
        multipleResults.add(defaultResultHandler.getResultList());
      } else {
        handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
      }
    } finally {

View on GitHub (pinned to 008069adb1)

Solutions

  1. Add resultType='com.example.Order' (or a resultMap reference) to the offending <select id=...> named in the message
  2. For annotation mappers, give the method a concrete return type (Order, List<Order>, Map<String,Object>) so MyBatis can derive resultType
  3. For statements invoked without a backing method, always declare the mapping explicitly in XML

Example fix

<!-- before -->
<select id="selectOrders" parameterType="long">
  SELECT * FROM orders WHERE customer_id = #{id}
</select>
<!-- after -->
<select id="selectOrders" parameterType="long" resultType="com.example.Order">
  SELECT * FROM orders WHERE customer_id = #{id}
</select>
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast at startup: every select statement must declare a result mapping
for (String id : sqlSessionFactory.getConfiguration().getMappedStatementNames()) {
  MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id);
  if (ms.getSqlCommandType() == SqlCommandType.SELECT && ms.getResultMaps().isEmpty()) {
    throw new IllegalStateException("Statement missing resultType/resultMap: " + id);
  }
}

Prevention

When it happens

Trigger: handleResultSets/handleCursorResultSets runs with rsw != null and mappedStatement.getResultMaps().size() < 1 — a <select> node with neither resultType nor resultMap, or a mapper method return type MyBatis cannot infer (e.g. void or an unresolvable generic).

Common situations: Hand-written mapper XML forgetting resultType on a new <select>; annotation @Select without a matching return type on the interface method; refactoring that removes resultType while renaming; using Map-returning methods with ambiguous signatures.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/e1e286d82a95cfff. Report an issue: GitHub.