baomidou/mybatis-plus · error · BuilderException

Should be specified either value() or name() attribute in…

Error message

Should be specified either value() or name() attribute in the @CacheNamespaceRef

What it means

Thrown while parsing a mapper interface when @CacheNamespaceRef is present but neither of its attributes is set. The annotation needs either value() (a class whose cache to share) or name() (a namespace name); when value() is still the default void.class and name() is the empty string, the builder cannot determine the referenced cache and rejects the configuration.

Solutions

  1. Set value() to the mapper class whose cache to reference: @CacheNamespaceRef(UserMapper.class).
  2. Or set name() to the target namespace string: @CacheNamespaceRef(name = "com.example.UserMapper").
  3. If shared caching was not intended, remove the @CacheNamespaceRef annotation entirely.

Example fix

// before
@CacheNamespaceRef
public interface OrderMapper extends BaseMapper<Order> {}

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

Strategy: validation

Validate before calling

// reflectively validate @CacheNamespaceRef before factory build
Class<?> mapper = com.example.mapper.OrderMapper.class;
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 + " has @CacheNamespaceRef without value() or name()");
}

Try / catch

Catch BuilderException during configuration parse; message names the mapper — fix the annotation and restart. Not retryable.

Prevention

When it happens

Trigger: Declaring @CacheNamespaceRef with no attributes on a mapper interface: @CacheNamespaceRef public interface UserMapper {...}, leaving value() = void.class and name() = "".

Common situations: Copy-pasting a @CacheNamespaceRef declaration from another mapper and deleting the target class; IDE auto-importing CacheNamespaceRef while adding an unrelated annotation; upgrading MyBatis/MyBatis-Plus versions where previously lenient parsing now validates attributes.

Related errors


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

Appendix: source

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

    private Properties convertToProperties(Property[] properties) {
        if (properties.length == 0) {
            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);

View on GitHub (pinned to bf67d90747)