{"record":{"id":"8841c4bc7f4fda30","repo":"mybatis/mybatis-3","slug":"invalid-base-cache-implementation-base-cach","errorCode":null,"errorMessage":"Invalid base cache implementation ({}).  Base cache implementations must have a constructor that takes a String id as a parameter.  Cause: {}","messagePattern":"Invalid base cache implementation \\((.+?)\\)\\.  Base cache implementations must have a constructor that takes a String id as a parameter\\.  Cause: (.+?)","errorType":"validation","errorClass":"CacheException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/mapping/CacheBuilder.java","lineNumber":195,"sourceCode":"            \"Failed cache initialization for '\" + cache.getId() + \"' on '\" + cache.getClass().getName() + \"'\", e);\n      }\n    }\n  }\n\n  private Cache newBaseCacheInstance(Class<? extends Cache> cacheClass, String id) {\n    Constructor<? extends Cache> cacheConstructor = getBaseCacheConstructor(cacheClass);\n    try {\n      return cacheConstructor.newInstance(id);\n    } catch (Exception e) {\n      throw new CacheException(\"Could not instantiate cache implementation (\" + cacheClass + \"). Cause: \" + e, e);\n    }\n  }\n\n  private Constructor<? extends Cache> getBaseCacheConstructor(Class<? extends Cache> cacheClass) {\n    try {\n      return cacheClass.getConstructor(String.class);\n    } catch (Exception e) {\n      throw new CacheException(\"Invalid base cache implementation (\" + cacheClass + \").  \"\n          + \"Base cache implementations must have a constructor that takes a String id as a parameter.  Cause: \" + e,\n          e);\n    }\n  }\n\n  private Cache newCacheDecoratorInstance(Class<? extends Cache> cacheClass, Cache base) {\n    Constructor<? extends Cache> cacheConstructor = getCacheDecoratorConstructor(cacheClass);\n    try {\n      return cacheConstructor.newInstance(base);\n    } catch (Exception e) {\n      throw new CacheException(\"Could not instantiate cache decorator (\" + cacheClass + \"). Cause: \" + e, e);\n    }\n  }\n\n  private Constructor<? extends Cache> getCacheDecoratorConstructor(Class<? extends Cache> cacheClass) {\n    try {\n      return cacheClass.getConstructor(Cache.class);\n    } catch (Exception e) {","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/mapping/CacheBuilder.java#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic class MyCache implements Cache {\n  public MyCache() {} // no String-id constructor\n}\n\n// after\npublic class MyCache implements Cache {\n  private final String id;\n  public MyCache(String id) { this.id = id; }\n  @Override public String getId() { return id; }\n}","handlingStrategy":"validation","validationCode":"// Check the required constructor exists before use\ntry {\n  MyCache.class.getConstructor(String.class);\n} catch (NoSuchMethodException e) {\n  throw new IllegalStateException(\"MyCache must expose public MyCache(String id)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["mybatis","cache","constructor-contract","custom-cache"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}