mybatis/mybatis-3 · error · ExecutorException
Error instantiating collection property for result '{}'. Ca
Error message
Error instantiating collection property for result '{}'. Cause: {} What it means
MyBatis tried to lazily instantiate a collection property for a nested result (the property was null and its declared Java type is a collection) and the objectFactory.create(type) call threw — typically InstantiationException/AccessException because the collection type is abstract or has no no-arg constructor. The wrap names the resultMapping property and keeps the cause.
Source
Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:1645
return list.isEmpty() ? null : list.get(0);
}
private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {
final String propertyName = resultMapping.getProperty();
Object propertyValue = metaObject.getValue(propertyName);
if (propertyValue == null) {
Class<?> type = resultMapping.getJavaType();
if (type == null) {
type = metaObject.getSetterType(propertyName);
}
try {
if (objectFactory.isCollection(type)) {
propertyValue = objectFactory.create(type);
metaObject.setValue(propertyName, propertyValue);
return propertyValue;
}
} catch (Exception e) {
throw new ExecutorException(
"Error instantiating collection property for result '" + resultMapping.getProperty() + "'. Cause: " + e,
e);
}
} else if (objectFactory.isCollection(propertyValue.getClass())) {
return propertyValue;
}
return null;
}
private boolean hasTypeHandlerForResultObject(ResultSetWrapper rsw, Class<?> resultType) {
if (rsw.getColumnNames().size() == 1) {
return typeHandlerRegistry.hasTypeHandler(resultType, rsw.getJdbcType(rsw.getColumnNames().get(0)));
}
return typeHandlerRegistry.hasTypeHandler(resultType);
}
}
View on GitHub (pinned to 008069adb1)
Solutions
- Use a concrete collection type for the property/mapping javaType (java.util.ArrayList, java.util.LinkedHashSet, etc.).
- If the property's declared setter type is already concrete, remove the explicit javaType so MyBatis derives it from the setter.
- Give custom collection classes a public no-arg constructor, or configure an ObjectFactory that knows how to build them.
- Register a custom DefaultObjectFactory that handles your collection types.
Example fix
<!-- before --> <collection property="items" ofType="Item" javaType="java.util.List"/> <!-- after --> <collection property="items" ofType="Item" javaType="java.util.ArrayList"/> <!-- or simply omit javaType if the setter type is concrete -->
Defensive patterns
Strategy: validation
Validate before calling
// assert the nested collection property type is instantiable before first use
Class<?> t = resultMapping.getJavaType() != null
? resultMapping.getJavaType()
: metaObject.getSetterType(propertyName);
if (objectFactory.isCollection(t) && (Modifier.isAbstract(t.getModifiers())
|| Arrays.stream(t.getConstructors()).noneMatch(c -> c.getParameterCount() == 0))) {
throw new IllegalStateException(t + " is a collection without a public no-arg constructor;");
} Type guard
static boolean instantiableCollection(Class<?> c) {
return Collection.class.isAssignableFrom(c)
&& !Modifier.isAbstract(c.getModifiers())
&& Arrays.stream(c.getConstructors()).anyMatch(x -> x.getParameterCount() == 0);
} Prevention
- Declare concrete collection types (ArrayList, LinkedHashSet) on collection mappings, not interfaces.
- If mapping to custom collections, give them public no-arg constructors and cover them with a mapping unit test.
When it happens
Trigger: A nested collection mapping whose javaType is a non-instantiable collection (e.g. java.util.List, java.util.Collection, java.util.Set interfaces directly, or a custom collection lacking a public no-arg constructor); instantiateCollectionPropertyIfAppropriate runs before linking nested rows and object creation fails.
Common situations: Declaring javaType="java.util.List" instead of a concrete class on <collection>; custom ImmutableBag collection types; a custom ObjectFactory that rejects or fails to create collection classes; mapping onto a collection whose constructor requires arguments.
Related errors
- Do not know how to create an instance of " + resultType
- Cannot add a collection result to non-collection based resul
- Error instantiating {} with invalid types ({}) or values ({}
- Error creating instance. Cause: {cause}
- Could not find a parent resultMap with id '{extend}'
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/1213466b0f77e3df.
Report an issue: GitHub.