mybatis/mybatis-3 · error · TypeException

Could not find type handler for Java type '" + propertyGener

Error message

Could not find type handler for Java type '" + propertyGenericType.getTypeName() + "' nor JDBC type '" + actualJdbcType + "'

What it means

DefaultParameterHandler resolves a TypeHandler for each parameter before binding it to the PreparedStatement: first by (Java generic type + JDBC type), then by JDBC type alone, and only as a last resort by Java type. If all lookups fail it throws a TypeException listing the Java type (or the runtime value's class when no generic type was known) and JDBC type — meaning no registered handler can write that combination to the driver.

Source

Thrown at src/main/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandler.java:170

          }
          if (value == null) {
            if (jdbcType == null) {
              jdbcType = configuration.getJdbcTypeForNull();
            }
            if (typeHandler == null) {
              typeHandler = ObjectTypeHandler.INSTANCE;
            }
          } else if (typeHandler == null) {
            if (propertyGenericType == null) {
              propertyGenericType = value.getClass();
            }
            typeHandler = typeHandlerRegistry.getTypeHandler(propertyGenericType, actualJdbcType, null);
          }
          if (typeHandler == null) {
            typeHandler = typeHandlerRegistry.getTypeHandler(actualJdbcType);
          }
          if (typeHandler == null) {
            throw new TypeException("Could not find type handler for Java type '" + propertyGenericType.getTypeName()
                + "' nor JDBC type '" + actualJdbcType + "'");
          }
          try {
            typeHandler.setParameter(ps, i + 1, value, jdbcType);
          } catch (TypeException | SQLException e) {
            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
          }
        }
      }
    }
  }

  private MetaObject getParamMetaObject() {
    if (paramMetaObject != null) {
      return paramMetaObject;
    }
    paramMetaObject = configuration.newMetaObject(parameterObject);
    return paramMetaObject;

View on GitHub (pinned to 008069adb1)

Solutions

  1. Write a TypeHandler for the parameter type and register it in the config (<typeHandlers> or Configuration.getTypeHandlerRegistry().register(...))
  2. Specify the handler explicitly on the mapping: #{value,typeHandler=com.example.MyTypeHandler}
  3. Pass a supported primitive/wrapper/String representation of the value instead of the custom object
  4. For nulls/odd jdbcTypes, declare javaType and jdbcType on the #{...} placeholder so resolution succeeds

Example fix

<!-- before -->
#{body}  <!-- body is a custom JsonValue type -->

<!-- after -->
#{body,typeHandler=com.example.JsonTypeHandler,jdbcType=VARCHAR}
Defensive patterns

Strategy: validation

Validate before calling

TypeHandler<?> h = typeHandlerRegistry.getTypeHandler(value != null ? value.getClass() : String.class, jdbcType);
if (h == null) {
  // register or specify a handler BEFORE executing the statement
  throw new IllegalStateException("No type handler for " + value.getClass());
}

Try / catch

try {
  session.selectList("stmt", params);
} catch (TypeException e) {
  if (e.getMessage().contains("Could not find type handler")) {
    // register handler: configuration.getTypeHandlerRegistry().register(MyType.class, new MyHandler()); then retry
  } else throw e;
}

Prevention

When it happens

Trigger: A parameter whose Java type has no registered handler (custom value objects, exotic JDK types) and no typeHandler specified on the mapping; javaType/jdbcType combination with no handler (e.g. an Enum without default handling in unusual configurations); null javaType on a mapping whose runtime value is a custom class.

Common situations: Passing domain objects/adapters as parameters without a TypeHandler; migrating to MyBatis versions where handler registry resolution for generics became stricter; custom JDBC types not covered by BaseTypeHandler registrations.

Related errors


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