mybatis/mybatis-3 · error · CacheException
Invalid base cache implementation ({}). Base cache implemen
Error message
Invalid base cache implementation ({}). Base cache implementations must have a constructor that takes a String id as a parameter. Cause: {} What it means
CacheBuilder.getBaseCacheConstructor() throws CacheException when the cache class used as the base implementation (type= attribute of <cache>, or CacheBuilder.implementation) has no public constructor taking a single String id. MyBatis requires the contract Cache(String id) so it can create the instance with the namespace as id.
Source
Thrown at src/main/java/org/apache/ibatis/mapping/CacheBuilder.java:195
"Failed cache initialization for '" + cache.getId() + "' on '" + cache.getClass().getName() + "'", e);
}
}
}
private Cache newBaseCacheInstance(Class<? extends Cache> cacheClass, String id) {
Constructor<? extends Cache> cacheConstructor = getBaseCacheConstructor(cacheClass);
try {
return cacheConstructor.newInstance(id);
} catch (Exception e) {
throw new CacheException("Could not instantiate cache implementation (" + cacheClass + "). Cause: " + e, e);
}
}
private Constructor<? extends Cache> getBaseCacheConstructor(Class<? extends Cache> cacheClass) {
try {
return cacheClass.getConstructor(String.class);
} catch (Exception e) {
throw new CacheException("Invalid base cache implementation (" + cacheClass + "). "
+ "Base cache implementations must have a constructor that takes a String id as a parameter. Cause: " + e,
e);
}
}
private Cache newCacheDecoratorInstance(Class<? extends Cache> cacheClass, Cache base) {
Constructor<? extends Cache> cacheConstructor = getCacheDecoratorConstructor(cacheClass);
try {
return cacheConstructor.newInstance(base);
} catch (Exception e) {
throw new CacheException("Could not instantiate cache decorator (" + cacheClass + "). Cause: " + e, e);
}
}
private Constructor<? extends Cache> getCacheDecoratorConstructor(Class<? extends Cache> cacheClass) {
try {
return cacheClass.getConstructor(Cache.class);
} catch (Exception e) {View on GitHub (pinned to 008069adb1)
Solutions
- Add a public constructor public MyCache(String id) { this.id = id; } to the cache implementation.
- Make sure you are not specifying a decorator class in the type= attribute — decorators take a Cache, not a String.
- Keep setters for the remaining configuration so <property> entries still work.
Example fix
// before
public class MyCache implements Cache {
public MyCache() {} // no String-id constructor
}
// after
public class MyCache implements Cache {
private final String id;
public MyCache(String id) { this.id = id; }
@Override public String getId() { return id; }
} Defensive patterns
Strategy: validation
Validate before calling
// Check the required constructor exists before use
try {
MyCache.class.getConstructor(String.class);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("MyCache must expose public MyCache(String id)");
} Prevention
- Code-review custom caches for the public (String id) constructor contract.
- Do not point type= at decorator or abstract classes.
- Add an architecture test (e.g. ArchUnit/reflection smoke test) asserting the constructor on every Cache implementation.
When it happens
Trigger: Declaring <cache type="com.x.MyCache"/> where MyCache has only a no-arg constructor, a constructor with different parameter types, or a non-public constructor.
Common situations: Porting caches written for other DI frameworks (which expect no-arg construction + setters); forgetting to make the constructor public; accidentally pointing type= at a decorator class instead of a base cache.
Related errors
- Failed cache initialization for '{}' on '{}'
- Could not instantiate cache implementation ({}). Cause: {}
- Invalid cache decorator ({}). Cache decorators must have a
- cache-ref element requires a namespace attribute.
- No cache for namespace '{namespace}' could be found.
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/8841c4bc7f4fda30.
Report an issue: GitHub.