baomidou/mybatis-plus · error · BuilderException

Cannot use both value() and name() attribute in the @CacheNa

Error message

Cannot use both value() and name() attribute in the @CacheNamespaceRef

What it means

Thrown while parsing a mapper interface when @CacheNamespaceRef specifies both value() and name(). These two attributes are alternative ways to identify the referenced cache namespace (class vs string), and supplying both is contradictory, so the builder rejects it to avoid guessing which one wins.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java:189

            return null;
        }
        Properties props = new Properties();
        for (Property property : properties) {
            props.setProperty(property.name(), PropertyParser.parse(property.value(), configuration.getVariables()));
        }
        return props;
    }

    private void parseCacheRef() {
        CacheNamespaceRef cacheDomainRef = type.getAnnotation(CacheNamespaceRef.class);
        if (cacheDomainRef != null) {
            Class<?> refType = cacheDomainRef.value();
            String refName = cacheDomainRef.name();
            if (refType == void.class && refName.isEmpty()) {
                throw new BuilderException("Should be specified either value() or name() attribute in the @CacheNamespaceRef");
            }
            if (refType != void.class && !refName.isEmpty()) {
                throw new BuilderException("Cannot use both value() and name() attribute in the @CacheNamespaceRef");
            }
            String namespace = refType != void.class ? refType.getName() : refName;
            try {
                assistant.useCacheRef(namespace);
            } catch (IncompleteElementException e) {
                configuration.addIncompleteCacheRef(new CacheRefResolver(assistant, namespace));
            }
        }
    }

    private String parseResultMap(Method method) {
        Class<?> returnType = getReturnType(method, type);
        Arg[] args = method.getAnnotationsByType(Arg.class);
        Result[] results = method.getAnnotationsByType(Result.class);
        TypeDiscriminator typeDiscriminator = method.getAnnotation(TypeDiscriminator.class);
        String resultMapId = generateResultMapName(method);
        applyResultMap(resultMapId, returnType, args, results, typeDiscriminator);
        return resultMapId;

View on GitHub (pinned to bf67d90747)

Solutions

  1. Keep exactly one attribute: prefer the type-safe value() form @CacheNamespaceRef(UserMapper.class).
  2. If the target is not a compile-time-visible class (e.g. XML-only namespace), keep only name() and delete value().
  3. Re-run the application to confirm mapper parsing succeeds.

Example fix

// before
@CacheNamespaceRef(value = UserMapper.class, name = "com.example.UserMapper")
public interface OrderMapper extends BaseMapper<Order> {}

// after
@CacheNamespaceRef(UserMapper.class)
public interface OrderMapper extends BaseMapper<Order> {}
Defensive patterns

Strategy: validation

Validate before calling

org.apache.ibatis.annotations.CacheNamespaceRef ref = mapper.getAnnotation(org.apache.ibatis.annotations.CacheNamespaceRef.class);
if (ref != null && ref.value() != void.class && !ref.name().isEmpty()) {
    throw new IllegalStateException(mapper + " sets both value() and name() in @CacheNamespaceRef");
}

Try / catch

Catch BuilderException at parse time; message identifies the mapper — remove one attribute and rebuild.

Prevention

When it happens

Trigger: Declaring @CacheNamespaceRef(value = UserMapper.class, name = "com.example.UserMapper") on a mapper interface; refType != void.class and refName is non-empty in parseCacheRef().

Common situations: Refactoring from name-based to class-based references and leaving both attributes populated; IDE generating stub attribute values when adding the annotation.

Related errors


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