mybatis/mybatis-3 · error · CacheException
Unsupported property type for cache: '{}' of type {}
Error message
Unsupported property type for cache: '{}' of type {} What it means
CacheBuilder.setCacheProperties() throws CacheException when a cache property declared in <cache ...> or CacheBuilder.properties has a setter whose type is not one of the supported ones (String, int/Integer, long/Long, short/Short, byte/Byte, float/Float, boolean/Boolean, double/Double). MyBatis reflects values as strings from XML and only converts to those primitive-ish types.
Source
Thrown at src/main/java/org/apache/ibatis/mapping/CacheBuilder.java:167
Class<?> type = metaCache.getSetterType(name);
if (String.class == type) {
metaCache.setValue(name, value);
} else if (int.class == type || Integer.class == type) {
metaCache.setValue(name, Integer.valueOf(value));
} else if (long.class == type || Long.class == type) {
metaCache.setValue(name, Long.valueOf(value));
} else if (short.class == type || Short.class == type) {
metaCache.setValue(name, Short.valueOf(value));
} else if (byte.class == type || Byte.class == type) {
metaCache.setValue(name, Byte.valueOf(value));
} else if (float.class == type || Float.class == type) {
metaCache.setValue(name, Float.valueOf(value));
} else if (boolean.class == type || Boolean.class == type) {
metaCache.setValue(name, Boolean.valueOf(value));
} else if (double.class == type || Double.class == type) {
metaCache.setValue(name, Double.valueOf(value));
} else {
throw new CacheException("Unsupported property type for cache: '" + name + "' of type " + type);
}
}
}
}
if (InitializingObject.class.isAssignableFrom(cache.getClass())) {
try {
((InitializingObject) cache).initialize();
} catch (Exception e) {
throw new CacheException(
"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);View on GitHub (pinned to 008069adb1)
Solutions
- Change the cache implementation's setter to accept String and parse internally (e.g. setTimeUnit(String name) { this.unit = TimeUnit.valueOf(name); }).
- Or expose an int/long setter and pass the raw value, converting internally.
- If you control construction, configure the cache object before handing it to MyBatis and use <cache type> with only primitive properties.
Example fix
// before
public class MyCache implements Cache {
public void setTimeUnit(TimeUnit unit) { ... } // unsupported type
}
// after
public class MyCache implements Cache {
public void setTimeUnit(String unit) { this.unit = TimeUnit.valueOf(unit); }
} Defensive patterns
Strategy: validation
Validate before calling
// Before wiring properties, check every setter type is supported
Set<Class<?>> supported = Set.of(String.class, int.class, Integer.class, long.class, Long.class,
short.class, Short.class, byte.class, Byte.class, float.class, Float.class,
boolean.class, Boolean.class, double.class, Double.class);
for (Method m : MyCache.class.getMethods()) {
if (m.getName().startsWith("set") && m.getParameterCount() == 1
&& !supported.contains(m.getParameterTypes()[0])) {
throw new IllegalStateException("Unsupported cache property setter: " + m);
}
} Prevention
- Expose only String/primitive setters on cache implementations meant for <property> config.
- Parse richer types (enums, durations) inside String setters, not in setter signatures.
- Document each supported property name and type on the custom cache class.
When it happens
Trigger: Configuring a custom cache with a property whose setter takes another type, e.g. setTimeUnit(TimeUnit), setMemoryLimit(BigDecimal), or an enum setter, via <cache type="com.x.MyCache"><property name="timeUnit" value="SECONDS"/></cache>.
Common situations: Adapting third-party caches (Infinispan, Hazelcast, custom) to MyBatis where configuration setters naturally use richer types than primitives; copying config from another framework that supports typed properties.
Related errors
- Error creating instance. Cause: {cause}
- cache-ref element requires a namespace attribute.
- Should be specified either value() or name() attribute in th
- Cannot use both value() and name() attribute in the @CacheNa
- Cannot get Configuration as factory method [" + this.configu
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/72fa7d7f4b9e8d84.
Report an issue: GitHub.