mybatis/mybatis-3 · error · IncompleteElementException

No cache for namespace '{namespace}' could be found.

Error message

No cache for namespace '{namespace}' could be found.

What it means

Thrown by useCacheRef() when configuration.getCache(namespace) returns null: the target namespace has no cache registered yet. Unlike a plain BuilderException, this is an IncompleteElementException, signaling MyBatis that the mapper may simply be parsed before the cache-defining mapper, so parsing is retried after all mappers are loaded.

Source

Thrown at src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java:117

      if (base.startsWith(currentNamespace + ".")) {
        return base;
      }
      if (base.contains(".")) {
        throw new BuilderException("Dots are not allowed in element names, please remove it from " + base);
      }
    }
    return currentNamespace + "." + base;
  }

  public Cache useCacheRef(String namespace) {
    if (namespace == null) {
      throw new BuilderException("cache-ref element requires a namespace attribute.");
    }
    try {
      unresolvedCacheRef = true;
      Cache cache = configuration.getCache(namespace);
      if (cache == null) {
        throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.");
      }
      currentCache = cache;
      unresolvedCacheRef = false;
      return cache;
    } catch (IllegalArgumentException e) {
      throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.", e);
    }
  }

  public Cache useNewCache(Class<? extends Cache> typeClass, Class<? extends Cache> evictionClass, Long flushInterval,
      Integer size, boolean readWrite, boolean blocking, Properties props) {
    Cache cache = new CacheBuilder(currentNamespace).implementation(valueOrDefault(typeClass, PerpetualCache.class))
        .addDecorator(valueOrDefault(evictionClass, LruCache.class)).clearInterval(flushInterval).size(size)
        .readWrite(readWrite).blocking(blocking).properties(props).build();
    configuration.addCache(cache);
    currentCache = cache;
    return cache;
  }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Verify the target mapper declares a cache: add <cache/> (or a customized <cache type=... eviction=.../>) to the referenced XML mapper, or @CacheNamespace on the referenced interface
  2. Double-check the namespace string matches the referenced mapper's namespace attribute exactly (fully qualified, case-sensitive)
  3. If the error persists after all mappers are loaded, the referenced namespace is misspelled or its mapper is not registered in mybatis-config.xml / being scanned

Example fix

<!-- before: UserMapper has cache-ref but RoleMapper has no cache -->
<cache-ref namespace="com.acme.RoleMapper"/>
<!-- after: add to RoleMapper.xml -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
Defensive patterns

Strategy: validation

Validate before calling

// Before SqlSessionFactory build: verify every cache-ref namespace has a cache owner
Set<String> cacheOwners = new HashSet<>();
// collect namespaces of mappers that declare <cache> or @CacheNamespace
for (MapperMetadata m : allMappers) {
  if (m.declaresCache()) cacheOwners.add(m.getNamespace());
}
for (String refNs : collectCacheRefNamespaces()) {
  if (!cacheOwners.contains(refNs)) throw new IllegalStateException("cache-ref target has no cache: " + refNs);
}

Try / catch

try {
  session.getConfiguration().getCache(refNamespace);
} catch (Exception e) {
  // treat as configuration bug, not runtime: fail startup loudly
  throw new IllegalStateException("cache-ref target missing: " + refNamespace, e);
}

Prevention

When it happens

Trigger: <cache-ref namespace="X"/> where mapper X has no <cache> element at all, or where X is parsed after the referencing mapper (normal cross-mapper ordering). Also triggered from @CacheNamespaceRef parsing in MapperAnnotationBuilder.parseCacheRef().

Common situations: Referencing a mapper that never declared <cache>/@CacheNamespace (the ref is genuinely dangling), or ordering issues during configuration that resolve themselves on the second pass — a hard failure only appears if the cache never materializes.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/18b4e707503582c6. Report an issue: GitHub.