{"record":{"id":"e09c623ff96f381c","repo":"mybatis/mybatis-3","slug":"should-be-specified-either-value-or-name-attri","errorCode":null,"errorMessage":"Should be specified either value() or name() attribute in the @CacheNamespaceRef","messagePattern":"Should be specified either value\\(\\) or name\\(\\) attribute in the @CacheNamespaceRef","errorType":"exception","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java","lineNumber":214,"sourceCode":"\n  private Properties convertToProperties(Property[] properties) {\n    if (properties.length == 0) {\n      return null;\n    }\n    Properties props = new Properties();\n    for (Property property : properties) {\n      props.setProperty(property.name(), PropertyParser.parse(property.value(), configuration.getVariables()));\n    }\n    return props;\n  }\n\n  private void parseCacheRef() {\n    CacheNamespaceRef cacheDomainRef = type.getAnnotation(CacheNamespaceRef.class);\n    if (cacheDomainRef != null) {\n      Class<?> refType = cacheDomainRef.value();\n      String refName = cacheDomainRef.name();\n      if (refType == void.class && refName.isEmpty()) {\n        throw new BuilderException(\"Should be specified either value() or name() attribute in the @CacheNamespaceRef\");\n      }\n      if (refType != void.class && !refName.isEmpty()) {\n        throw new BuilderException(\"Cannot use both value() and name() attribute in the @CacheNamespaceRef\");\n      }\n      String namespace = refType != void.class ? refType.getName() : refName;\n      try {\n        assistant.useCacheRef(namespace);\n      } catch (IncompleteElementException e) {\n        configuration.addIncompleteCacheRef(new CacheRefResolver(assistant, namespace));\n      }\n    }\n  }\n\n  private String parseResultMap(Method method) {\n    Class<?> returnType = getReturnType(method, type);\n    Arg[] args = method.getAnnotationsByType(Arg.class);\n    Result[] results = method.getAnnotationsByType(Result.class);\n    TypeDiscriminator typeDiscriminator = method.getAnnotation(TypeDiscriminator.class);","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java#L196-L232","documentation":"Thrown by MapperAnnotationBuilder.parseCacheRef() when @CacheNamespaceRef is present but both attributes are unset: value() defaults to void.class and name() defaults to \"\". The annotation must say which namespace to borrow the cache from, via either the mapper class (value) or a string namespace (name).","triggerScenarios":"Writing @CacheNamespaceRef with no attributes on a mapper interface; defaults (void.class, empty string) fail the check.","commonSituations":"Assuming @CacheNamespaceRef works standalone like @CacheNamespace does; forgetting the target after refactoring; IDE auto-import picking the annotation without suggesting required attributes.","solutions":["Point the ref at the cache-owning mapper: @CacheNamespaceRef(UserMapper.class)","Or use the string form: @CacheNamespaceRef(name = \"com.acme.UserMapper\")","Confirm the referenced class declares @CacheNamespace (a ref to a mapper without a cache fails later with the incomplete-cache error)"],"exampleFix":"// before\n@CacheNamespaceRef\npublic interface OrderMapper { ... }\n// after\n@CacheNamespaceRef(UserMapper.class)\npublic interface OrderMapper { ... }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Compile-time guard: a wrapper annotation forcing an attribute\n@Retention(RetentionPolicy.SOURCE)\npublic @interface CacheRefTarget {\n  Class<?> value() default void.class;\n  String name() default \"\";\n}\n// runtime check before SqlSessionFactory build:\nfor (Class<?> mapper : scannedMappers) {\n  CacheNamespaceRef r = mapper.getAnnotation(CacheNamespaceRef.class);\n  if (r != null && r.value() == void.class && r.name().isEmpty()) {\n    throw new IllegalStateException(mapper + \" has @CacheNamespaceRef without value/name\");\n  }\n}","tryCatchPattern":null,"preventionTips":["Always write @CacheNamespaceRef with an explicit target; never rely on defaults","Prefer the class form @CacheNamespaceRef(OtherMapper.class) so a missing target breaks compilation"],"tags":["mybatis","cache","annotation","configuration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}