mybatis/mybatis-3 · error · IllegalStateException

Missing resultMap in property '{}'. Parameters of type java

Error message

Missing resultMap in property '{}'.  Parameters of type java.sql.ResultSet require a resultMap.

What it means

ParameterMapping.Builder.validate() throws IllegalStateException when a parameter is declared with javaType=java.sql.ResultSet (an OUT cursor of a stored procedure) but no resultMapId is set. ResultSet parameters need a resultMap so MyBatis knows how to map each row of the cursor; without one, mapping is undefined and the builder refuses.

Source

Thrown at src/main/java/org/apache/ibatis/mapping/ParameterMapping.java:115

    public Builder expression(String expression) {
      parameterMapping.expression = expression;
      return this;
    }

    public Builder value(Object value) {
      parameterMapping.value = value;
      return this;
    }

    public ParameterMapping build() {
      validate();
      return parameterMapping;
    }

    private void validate() {
      if (ResultSet.class.equals(parameterMapping.javaType) && parameterMapping.resultMapId == null) {
        throw new IllegalStateException("Missing resultMap in property '" + parameterMapping.property + "'.  "
            + "Parameters of type java.sql.ResultSet require a resultMap.");
      }
    }
  }

  public String getProperty() {
    return property;
  }

  /**
   * Used for handling output of callable statements.
   *
   * @return the mode
   */
  public ParameterMode getMode() {
    return mode;
  }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Add a resultMap attribute to the CALLABLE statement that defines the mapping for the cursor rows.
  2. If building mappings programmatically, call .resultMapId("someResultMap") on the ParameterMapping.Builder.
  3. Verify the referenced resultMap id actually exists in the mapper to avoid the next failure downstream.

Example fix

<!-- before -->
<select statementType="CALLABLE" parameterType="map">
  {call get_users(#{curOut,mode=OUT,javaType=java.sql.ResultSet})}
</select>

<!-- after -->
<resultMap id="userMap" type="User">
  <result property="id" column="ID"/>
  <result property="name" column="NAME"/>
</resultMap>
<select statementType="CALLABLE" parameterType="map" resultMap="userMap">
  {call get_users(#{curOut,mode=OUT,javaType=java.sql.ResultSet})}
</select>
Defensive patterns

Strategy: validation

Validate before calling

// When building callable statement parameters programmatically
if (ResultSet.class.equals(javaType) && resultMapId == null) {
  throw new IllegalStateException("ResultSet parameter '" + property + "' needs a resultMap");
}
new ParameterMapping.Builder(config, property, javaType)
    .mode(ParameterMode.OUT).resultMapId(resultMapId).build();

Prevention

When it happens

Trigger: XML like <parameter property="curOut" javaType="java.sql.ResultSet" mode="OUT"/> in a <select statementType="CALLABLE"> statement without a resultMap="..." attribute on the same statement; or ParameterMapping.Builder without .resultMapId(...) for a ResultSet javaType.

Common situations: Calling Oracle/PostgreSQL stored procedures returning REF CURSOR parameters; refactoring a statement and dropping the resultMap attribute; copy-paste of an IN-parameter mapping pattern onto a cursor OUT parameter.

Related errors


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