mybatis/mybatis-3 · error · IncompleteElementException

Could not find a parent resultMap with id '{extend}'

Error message

Could not find a parent resultMap with id '{extend}'

What it means

Thrown by addResultMap() when a <resultMap extends="..."> references a parent resultMap id that configuration.hasResultMap() cannot find at that moment. It is an IncompleteElementException: MyBatis collects the incomplete result map and retries after all mappers are parsed, because the parent frequently lives in a mapper parsed later. It becomes fatal only if the parent never appears.

Source

Thrown at src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java:164

      Integer numericScale) {
    resultMap = applyCurrentNamespace(resultMap, true);

    // Class parameterType = parameterMapBuilder.type();
    Class<?> javaTypeClass = resolveParameterJavaType(parameterType, property, javaType, jdbcType);
    TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, jdbcType, typeHandler);

    return new ParameterMapping.Builder(configuration, property, javaTypeClass).jdbcType(jdbcType)
        .resultMapId(resultMap).mode(parameterMode).numericScale(numericScale).typeHandler(typeHandlerInstance).build();
  }

  public ResultMap addResultMap(String id, Class<?> type, String extend, Discriminator discriminator,
      List<ResultMapping> resultMappings, Boolean autoMapping) {
    id = applyCurrentNamespace(id, false);
    extend = applyCurrentNamespace(extend, true);

    if (extend != null) {
      if (!configuration.hasResultMap(extend)) {
        throw new IncompleteElementException("Could not find a parent resultMap with id '" + extend + "'");
      }
      ResultMap resultMap = configuration.getResultMap(extend);
      List<ResultMapping> extendedResultMappings = new ArrayList<>(resultMap.getResultMappings());
      extendedResultMappings.removeAll(resultMappings);
      // Remove parent constructor if this resultMap declares a constructor.
      boolean declaresConstructor = false;
      for (ResultMapping resultMapping : resultMappings) {
        if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
          declaresConstructor = true;
          break;
        }
      }
      if (declaresConstructor) {
        extendedResultMappings.removeIf(resultMapping -> resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR));
      }
      resultMappings.addAll(extendedResultMappings);
    }
    ResultMap resultMap = new ResultMap.Builder(configuration, id, type, resultMappings, autoMapping)

View on GitHub (pinned to 008069adb1)

Solutions

  1. Verify the parent resultMap id and its namespace spelling; use the fully qualified name when the parent is in another mapper
  2. Make sure the mapper containing the parent is registered (mybatis-config.xml <mapper> entries, package scanning, or Spring mybatis mapperLocations covering the file)
  3. If the parent was renamed/removed, update or delete the extends attribute

Example fix

<!-- before -->
<resultMap id="extUser" type="User" extends="com.acme.BaseUserr">
<!-- after -->
<resultMap id="extUser" type="User" extends="com.acme.BaseUser">
Defensive patterns

Strategy: validation

Validate before calling

// After building Configuration, assert every resultMap 'extends' resolved
configuration.getResultMapNames().forEach(rmId -> {
  // MyBatis flattens inheritance at build time; simply assert referenced ids exist before build:
});
// pre-build check on the XML side:
for (Map.Entry<String, String> e : collectExtendsRefs()) { // childId -> parentId
  if (!definedResultMapIds.contains(e.getValue())) {
    throw new IllegalStateException("resultMap '" + e.getKey() + "' extends unknown '" + e.getValue() + "'");
  }
}

Try / catch

try {
  factory = new SqlSessionFactoryBuilder().build(configInputStream);
} catch (PersistenceException e) {
  Throwable root = ExceptionUtils.getRootCause(e);
  if (root.getMessage().contains("Could not find a parent resultMap")) {
    throw new ConfigurationException("Dangling resultMap extends: " + root.getMessage(), root);
  }
  throw e;
}

Prevention

When it happens

Trigger: <resultMap id="x" extends="someMissing.Map">, or extends pointing at a parent in another mapper file that is parsed later or not registered at all; also an extends value whose namespace prefix is wrong after applyCurrentNamespace(extend, true).

Common situations: Cross-mapper inheritance ordering during startup (usually self-heals), dangling extends after deleting/renaming a parent resultMap, or a typo in the parent id. Persistent failure means the parent is genuinely absent from the Configuration.

Related errors


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