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
- 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
- Double-check the namespace string matches the referenced mapper's namespace attribute exactly (fully qualified, case-sensitive)
- 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
- Define the <cache> element in one shared/base mapper and reference it consistently
- Add a startup assertion that walks all cache-ref targets and confirms each namespace has a cache
- Keep namespaces identical to fully-qualified interface names so refactors break compilation, not runtime
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
- Cache-ref not yet resolved
- cache-ref element requires a namespace attribute.
- Could not find a parent resultMap with id '{extend}'
- Could not find parameter map {parameterMapName}
- Could not find result map '{resultMapName}' referenced from
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/18b4e707503582c6.
Report an issue: GitHub.