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#loadXmlResource

View on GitHub (pinned to bf67d90747)

Solutions

  1. Add an explicit javaType (e.g. javaType="java.util.List") and ofType to the <collection>
  2. Better: reference a nested resultMap via resultMap="itemResultMap" on the <collection>
  3. Otherwise fix the property name or add a setter for it on the enclosing type
  4. 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

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


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/b8d484f1bc74381f. Report an issue: GitHub.