baomidou/mybatis-plus · error · BuilderException
Ambiguous collection type for property '%s'. You must specif
Error message
Ambiguous collection type for property '%s'. You must specify 'javaType' or 'resultMap'.
What it means
A <collection> element in a resultMap declares neither 'resultMap' nor 'javaType', and the enclosing result type has no setter for the named property, so MyBatis cannot infer the collection's element/target type. MyBatis-Plus adds this validation to surface the ambiguity at parse time instead of failing obscurely at mapping time.
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLMapperBuilder.java:381
private String processNestedResultMappings(XNode context, List<ResultMapping> resultMappings,
Class<?> enclosingType) {
if (Arrays.asList("association", "collection", "case").contains(context.getName())
&& context.getStringAttribute("select") == null) {
validateCollection(context, enclosingType);
ResultMap resultMap = resultMapElement(context, resultMappings, enclosingType);
return resultMap.getId();
}
return null;
}
protected void validateCollection(XNode context, Class<?> enclosingType) {
if ("collection".equals(context.getName()) && context.getStringAttribute("resultMap") == null
&& context.getStringAttribute("javaType") == null) {
MetaClass metaResultType = MetaClass.forClass(enclosingType, configuration.getReflectorFactory());
String property = context.getStringAttribute("property");
if (!metaResultType.hasSetter(property)) {
throw new BuilderException(
"Ambiguous collection type for property '" + property + "'. You must specify 'javaType' or 'resultMap'.");
}
}
}
private void bindMapperForNamespace() {
String namespace = builderAssistant.getCurrentNamespace();
if (namespace != null) {
Class<?> boundType = null;
try {
boundType = Resources.classForName(namespace);
} catch (ClassNotFoundException e) {
// ignore, bound type is not required
}
if (boundType != null && !configuration.hasMapper(boundType)) {
// Spring may not know the real resource name so we set a flag
// to prevent loading again this resource from the mapper interface
// look at MapperAnnotationBuilder#loadXmlResourceView on GitHub (pinned to bf67d90747)
Solutions
- Add an explicit javaType (e.g. javaType="java.util.List") and ofType to the <collection>
- Better: reference a nested resultMap via resultMap="itemResultMap" on the <collection>
- Otherwise fix the property name or add a setter for it on the enclosing type
- If using Lombok, confirm annotation processing is enabled so setters are generated
Example fix
<!-- before --> <collection property="orderItems" ofType="com.example.Item"/> <!-- after --> <collection property="orderItems" javaType="java.util.ArrayList" ofType="com.example.Item"/> <!-- or --> <collection property="orderItems" resultMap="itemResultMap"/>
Defensive patterns
Strategy: validation
Validate before calling
// Unit-test your resultMaps against the enclosing type before shipping:
MetaClass mc = MetaClass.forClass(Order.class, new DefaultReflectorFactory());
if (!mc.hasSetter("orderItems")) throw new IllegalStateException("resultMap property 'orderItems' has no setter"); Prevention
- Always specify resultMap or javaType+ofType on <collection> elements
- Mirror every resultMap with a mapping unit test (call sqlSession select on a sample row in an H2 test)
- If using Lombok, keep @Data (with setters) on resultMap target DTOs
When it happens
Trigger: resultMap with <collection property="items"> where the enclosing class lacks a setItems(...) setter (or the property name is misspelled), and no javaType or resultMap attribute is provided on the collection.
Common situations: Renaming the Java property but not the XML; using a field with no setter (immutable DTO or Lombok @Value); Lombok not processed so setters are absent; nested collections where the wrong 'ofType'/'resultMap' was omitted.
Related errors
- Cannot use both @One and @Many annotations in the same @Resu
- Mapper's namespace cannot be empty
- Error parsing Mapper XML. The XML location is '%s'. Cause: %
- Unknown element <%s> in SQL statement.
- Too many default (otherwise) elements in choose statement.
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/b8d484f1bc74381f.
Report an issue: GitHub.