{"record":{"id":"1213466b0f77e3df","repo":"mybatis/mybatis-3","slug":"error-instantiating-collection-property-for-result","errorCode":null,"errorMessage":"Error instantiating collection property for result '{}'.  Cause: {}","messagePattern":"Error instantiating collection property for result '(.+?)'\\.  Cause: (.+?)","errorType":"exception","errorClass":"ExecutorException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java","lineNumber":1645,"sourceCode":"    return list.isEmpty() ? null : list.get(0);\n  }\n\n  private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {\n    final String propertyName = resultMapping.getProperty();\n    Object propertyValue = metaObject.getValue(propertyName);\n    if (propertyValue == null) {\n      Class<?> type = resultMapping.getJavaType();\n      if (type == null) {\n        type = metaObject.getSetterType(propertyName);\n      }\n      try {\n        if (objectFactory.isCollection(type)) {\n          propertyValue = objectFactory.create(type);\n          metaObject.setValue(propertyName, propertyValue);\n          return propertyValue;\n        }\n      } catch (Exception e) {\n        throw new ExecutorException(\n            \"Error instantiating collection property for result '\" + resultMapping.getProperty() + \"'.  Cause: \" + e,\n            e);\n      }\n    } else if (objectFactory.isCollection(propertyValue.getClass())) {\n      return propertyValue;\n    }\n    return null;\n  }\n\n  private boolean hasTypeHandlerForResultObject(ResultSetWrapper rsw, Class<?> resultType) {\n    if (rsw.getColumnNames().size() == 1) {\n      return typeHandlerRegistry.hasTypeHandler(resultType, rsw.getJdbcType(rsw.getColumnNames().get(0)));\n    }\n    return typeHandlerRegistry.hasTypeHandler(resultType);\n  }\n\n}\n","sourceCodeStart":1627,"sourceCodeEnd":1663,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java#L1627-L1663","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before -->\n<collection property=\"items\" ofType=\"Item\" javaType=\"java.util.List\"/>\n\n<!-- after -->\n<collection property=\"items\" ofType=\"Item\" javaType=\"java.util.ArrayList\"/>\n<!-- or simply omit javaType if the setter type is concrete -->","handlingStrategy":"validation","validationCode":"// assert the nested collection property type is instantiable before first use\nClass<?> t = resultMapping.getJavaType() != null\n    ? resultMapping.getJavaType()\n    : metaObject.getSetterType(propertyName);\nif (objectFactory.isCollection(t) && (Modifier.isAbstract(t.getModifiers())\n    || Arrays.stream(t.getConstructors()).noneMatch(c -> c.getParameterCount() == 0))) {\n  throw new IllegalStateException(t + \" is a collection without a public no-arg constructor;\");\n}","typeGuard":"static boolean instantiableCollection(Class<?> c) {\n  return Collection.class.isAssignableFrom(c)\n      && !Modifier.isAbstract(c.getModifiers())\n      && Arrays.stream(c.getConstructors()).anyMatch(x -> x.getParameterCount() == 0);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["mybatis","collections","instantiation","resultmap"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}