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
- Verify the parent resultMap id and its namespace spelling; use the fully qualified name when the parent is in another mapper
- Make sure the mapper containing the parent is registered (mybatis-config.xml <mapper> entries, package scanning, or Spring mybatis mapperLocations covering the file)
- 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
- Prefer fully-qualified parent ids in extends attributes
- When deleting/renaming a base resultMap, grep the whole project for its id
- Build the SqlSessionFactory in a unit test so inheritance issues surface at build time
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
- Could not find result map '{resultMapName}' referenced from
- No cache for namespace '{namespace}' could be found.
- Cache-ref not yet resolved
- Could not find parameter map {parameterMapName}
- 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/2244a3430b6841db.
Report an issue: GitHub.