mybatis/mybatis-3 · error · ExecutorException
No type handler found for '" + javaType + "' and JDBC type '
Error message
No type handler found for '" + javaType + "' and JDBC type '" + rsw.getJdbcType(column) + "'"
What it means
While applying a resultMapping, MyBatis found no TypeHandler able to convert the column's JDBC value to the property's Java type. The mapping did not pin a typeHandler, so the registry lookup with the property's Java type plus the JDBC type of the column (reported in the message) returned null.
Source
Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:604
return getNestedQueryMappingValue(rsw, metaResultObject, propertyMapping, lazyLoader, columnPrefix);
}
if (JdbcType.CURSOR.equals(propertyMapping.getJdbcType())) {
List<Object> results = getNestedCursorValue(rsw, propertyMapping, columnPrefix);
linkObjects(metaResultObject, propertyMapping, results.get(0), true);
return metaResultObject.getValue(propertyMapping.getProperty());
}
if (propertyMapping.getResultSet() != null) {
addPendingChildRelation(rs, metaResultObject, propertyMapping); // TODO is that OK?
return DEFERRED;
} else {
final String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
TypeHandler<?> typeHandler = propertyMapping.getTypeHandler();
if (typeHandler == null) {
final String property = propertyMapping.getProperty();
final Type javaType = property == null ? null : metaResultObject.getGenericSetterType(property).getKey();
typeHandler = rsw.getTypeHandler(javaType, column);
if (typeHandler == null) {
throw new ExecutorException(
"No type handler found for '" + javaType + "' and JDBC type '" + rsw.getJdbcType(column) + "'");
}
}
return typeHandler.getResult(rs, column);
}
}
private List<Object> getNestedCursorValue(ResultSetWrapper rsw, ResultMapping propertyMapping,
String parentColumnPrefix) throws SQLException {
final String column = prependPrefix(propertyMapping.getColumn(), parentColumnPrefix);
ResultMap nestedResultMap = resolveDiscriminatedResultMap(rsw,
configuration.getResultMap(propertyMapping.getNestedResultMapId()),
getColumnPrefix(parentColumnPrefix, propertyMapping));
ResultSetWrapper nestedRsw = new ResultSetWrapper(rsw.getResultSet().getObject(column, ResultSet.class),
configuration);
List<Object> results = new ArrayList<>();
handleResultSet(nestedRsw, nestedResultMap, results, null);
return results;View on GitHub (pinned to 008069adb1)
Solutions
- Register a TypeHandler for the exact javaType/JdbcType pair: configuration.getTypeHandlerRegistry().register(MyType.class, JdbcType.X, new MyHandler())
- Or specify the handler inline on the mapping: <result property="p" column="c" typeHandler="com.example.MyHandler"/>
- Change the property to a supported Java type (String, LocalDate on 3.4.5+) and convert in a setter
- Upgrade MyBatis — newer versions ship handlers for more java.time and enum combinations
Example fix
<!-- before -->
<result property="created" column="created_at" javaType="java.time.Instant"/>
<!-- after -->
<result property="created" column="created_at" javaType="java.time.Instant"
typeHandler="org.apache.ibatis.type.InstantTypeHandler"/> Defensive patterns
Strategy: validation
Validate before calling
// Before running, confirm a handler exists for the pair
TypeHandlerRegistry thr = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
TypeHandler<?> h = thr.getTypeHandler(Year.class, JdbcType.INTEGER);
if (h == null || h instanceof UnknownTypeHandler) { thr.register(Year.class, JdbcType.INTEGER, new YearTypeHandler()); } Try / catch
try { session.selectList("sel.statements"); } catch (ExecutorException e) { if (e.getMessage() != null && e.getMessage().contains("No type handler found")) { register handler from the message's java/jdbc pair and retry once; } else throw e; } Prevention
- Register custom TypeHandlers in a mybatis-config <typeHandlers> block or a TypeHandlerRegistry bootstrap
- Prefer mainstream java types (LocalDate, Instant on recent versions) for columns
- Add an integration test per exotic column type
When it happens
Trigger: getPropertyMappingValue with propertyMapping.getTypeHandler()==null and rsw.getTypeHandler(javaType, column) returning null — e.g. mapping an exotic javaType (some custom enum-ish type, java.time type in old versions) to an unusual JDBC type, or an enum property against a column with no string/numeric handler match.
Common situations: Mapping java.time.Instant/Year/ZoneId on older MyBatis versions; custom value classes without registering a TypeHandler; dialects returning odd JDBC type codes (e.g. Oracle TIMESTAMP_WITH_LOCAL_TZ) unknown to the registry; enums stored as custom DB types.
Related errors
- Error resolving JdbcType. Cause: {cause}
- Ambiguous collection type for property '{property}'. You mus
- Two different properties are mapped to the same resultSet
- Could not process result for mapping: " + constructorMapping
- Mapping is missing column attribute for property {}
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/ace208575684b05e.
Report an issue: GitHub.