mybatis/mybatis-3 · error · ExecutorException
Nested lazy loaded result property '" + property + "' for qu
Error message
Nested lazy loaded result property '" + property + "' for query id '" + resultLoader.mappedStatement.getId() + " already exists in the result map. The leftmost property of all lazy loaded properties must be unique within a result map."
What it means
ResultLoaderMap keys pending lazy loads by the LEFTMOST segment of the property path (order.customer -> 'order'). Two lazy properties in one resultMap that share the same leftmost segment would fight over the same loader slot and overwrite each other, so addLoader rejects the second one with this ExecutorException. Note the message contains a known typo ('query id ... already exists' string concatenation).
Source
Thrown at src/main/java/org/apache/ibatis/executor/loader/ResultLoaderMap.java:55
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
/**
* @author Clinton Begin
* @author Franta Mejta
*/
public class ResultLoaderMap {
private final Map<String, LoadPair> loaderMap = new HashMap<>();
public void addLoader(String property, MetaObject metaResultObject, ResultLoader resultLoader) {
String upperFirst = getUppercaseFirstProperty(property);
if (!upperFirst.equalsIgnoreCase(property) && loaderMap.containsKey(upperFirst)) {
throw new ExecutorException("Nested lazy loaded result property '" + property + "' for query id '"
+ resultLoader.mappedStatement.getId()
+ " already exists in the result map. The leftmost property of all lazy loaded properties must be unique within a result map.");
}
loaderMap.put(upperFirst, new LoadPair(property, metaResultObject, resultLoader));
}
public final Map<String, LoadPair> getProperties() {
return new HashMap<>(this.loaderMap);
}
public Set<String> getPropertyNames() {
return loaderMap.keySet();
}
public int size() {
return loaderMap.size();
}
View on GitHub (pinned to 008069adb1)
Solutions
- Give the two lazy properties distinct leftmost segments, e.g. property="pendingOrders" and property="shippedOrders"
- Combine them into a single nested select that populates the shared parent in one query
Example fix
<!-- before --> <resultMap id="m" type="T"> <association property="orders.pending" select="selPending" fetchType="lazy"/> <association property="orders.shipped" select="selShipped" fetchType="lazy"/> </resultMap> <!-- after --> <resultMap id="m" type="T"> <association property="pendingOrders" select="selPending" fetchType="lazy"/> <association property="shippedOrders" select="selShipped" fetchType="lazy"/> </resultMap>
Defensive patterns
Strategy: validation
Validate before calling
// Lint resultMaps: no two lazy properties may share a leftmost segment
Set<String> leftmost = new HashSet<>();
for (String prop : lazyPropertyPaths) {
String head = prop.split("\\.")[0];
if (!leftmost.add(head)) throw new IllegalStateException("duplicate leftmost lazy property: " + head);
} Prevention
- Keep one nested select per top-level lazy property in each resultMap
- Review resultMaps after splitting associations into sub-properties
When it happens
Trigger: A resultMap declaring two nested selects whose property paths start with the same segment, e.g. property="orders.pending" and property="orders.shipped" — both map to key 'orders'.
Common situations: Splitting one association into multiple lazy sub-properties under the same parent name; refactoring resultMaps during entity redesign.
Related errors
- Could not find a parent resultMap with id '{extend}'
- Could not find result map '{resultMapName}' referenced from
- Error in result map '{resultMapId}'. Failed to find a constr
- Error in result map '{resultMapId}'. We do not support parti
- If there is no type discriminator, then the NamedResultMap a
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/3cbe59de6a92cd6e.
Report an issue: GitHub.