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

  1. Add a public constructor public MyCache(String id) { this.id = id; } to the cache implementation.
  2. Make sure you are not specifying a decorator class in the type= attribute — decorators take a Cache, not a String.
  3. 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

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


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