mybatis/mybatis-3 · error · BuilderException
Type {typeHandlerType} is not a valid TypeHandler because it
Error message
Type {typeHandlerType} is not a valid TypeHandler because it does not implement TypeHandler interface What it means
When a typeHandler alias is resolved from configuration (XML attribute or annotation string), BaseBuilder verifies the resulting class actually implements org.apache.ibatis.type.TypeHandler. A class that resolves fine but is not a TypeHandler implementation fails with this BuilderException.
Source
Thrown at src/main/java/org/apache/ibatis/builder/BaseBuilder.java:122
throw new BuilderException("Error resolving class. Cause: " + e, e);
}
}
@Deprecated(since = "3.6.0", forRemoval = true)
protected TypeHandler<?> resolveTypeHandler(Class<?> javaType, String typeHandlerAlias) {
return resolveTypeHandler(javaType, null, typeHandlerAlias);
}
@Deprecated(since = "3.6.0", forRemoval = true)
protected TypeHandler<?> resolveTypeHandler(Class<?> javaType, Class<? extends TypeHandler<?>> typeHandlerType) {
return resolveTypeHandler(javaType, null, typeHandlerType);
}
protected TypeHandler<?> resolveTypeHandler(Type propertyType, JdbcType jdbcType, String typeHandlerAlias) {
Class<? extends TypeHandler<?>> typeHandlerType = null;
typeHandlerType = resolveClass(typeHandlerAlias);
if (typeHandlerType != null && !TypeHandler.class.isAssignableFrom(typeHandlerType)) {
throw new BuilderException("Type " + typeHandlerType.getName()
+ " is not a valid TypeHandler because it does not implement TypeHandler interface");
}
return resolveTypeHandler(propertyType, jdbcType, typeHandlerType);
}
protected TypeHandler<?> resolveTypeHandler(Type javaType, JdbcType jdbcType,
Class<? extends TypeHandler<?>> typeHandlerType) {
if (typeHandlerType == null && jdbcType == null) {
return null;
}
return configuration.getTypeHandlerRegistry().getTypeHandler(javaType, jdbcType, typeHandlerType);
}
protected <T> Class<? extends T> resolveAlias(String alias) {
return typeAliasRegistry.resolveAlias(alias);
}
}
View on GitHub (pinned to 008069adb1)
Solutions
- Make the referenced class implement/extend TypeHandler/BaseTypeHandler<T>
- Eliminate duplicate mybatis jars on the classpath so a single TypeHandler interface is used
- Recompile custom handlers against the mybatis version in use
Example fix
<!-- before -->
<result column="data" property="data" typeHandler="com.example.JsonUtil"/>
<!-- after -->
public class JsonTypeHandler extends BaseTypeHandler<MyJson> { ... }
<result column="data" property="data" typeHandler="com.example.JsonTypeHandler"/> Defensive patterns
Strategy: type-guard
Validate before calling
Class<?> c = Class.forName(typeHandlerName);
if (!org.apache.ibatis.type.TypeHandler.class.isAssignableFrom(c)) {
throw new IllegalStateException(typeHandlerName + " is not a TypeHandler");
} Type guard
static boolean isTypeHandler(Class<?> c) {
return org.apache.ibatis.type.TypeHandler.class.isAssignableFrom(c);
} Prevention
- Extend BaseTypeHandler<T> for custom handlers - it guarantees the interface
- Run 'mvn dependency:tree' to eliminate duplicate mybatis versions
When it happens
Trigger: typeHandler="com.example.SomeUtil" where SomeUtil is a plain utility class; passing a class that only extends a BaseTypeHandler indirectly through generics but was compiled against an incompatible mybatis version (binary incompatibility); specifying a TypeException class or ResultSetHandler where a TypeHandler was expected.
Common situations: Copy-pasting the wrong class name into a typeHandler attribute; multiple mybatis jar versions on the classpath so the class implements a different TypeHandler class (different classloader/package); upgrading MyBatis with a custom handler compiled against the old API.
Related errors
- Error resolving JdbcType. Cause: {cause}
- Error resolving ResultSetType. Cause: {cause}
- Error creating instance. Cause: {cause}
- Error resolving class. Cause: {cause}
- Type argument cannot be null
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/0ca817be59a68a1f.
Report an issue: GitHub.