mybatis/mybatis-3 · error · BuilderException
Error resolving JdbcType. Cause: {cause}
Error message
Error resolving JdbcType. Cause: {cause} What it means
BaseBuilder.resolveJdbcType() converts a configuration string (e.g. jdbcType attributes on #{...} placeholders, parameter/result mappings) into the JdbcType enum via valueOf(). Any string that is not an exact enum constant name throws IllegalArgumentException, wrapped into this BuilderException during parse time.
Source
Thrown at src/main/java/org/apache/ibatis/builder/BaseBuilder.java:71
protected Boolean booleanValueOf(String value, Boolean defaultValue) {
return value == null ? defaultValue : Boolean.valueOf(value);
}
protected Integer integerValueOf(String value, Integer defaultValue) {
return value == null ? defaultValue : Integer.valueOf(value);
}
protected Set<String> stringSetValueOf(String value, String defaultValue) {
value = value == null ? defaultValue : value;
return new HashSet<>(Arrays.asList(value.split(",")));
}
protected JdbcType resolveJdbcType(String alias) {
try {
return alias == null ? null : JdbcType.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving JdbcType. Cause: " + e, e);
}
}
protected ResultSetType resolveResultSetType(String alias) {
try {
return alias == null ? null : ResultSetType.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving ResultSetType. Cause: " + e, e);
}
}
protected ParameterMode resolveParameterMode(String alias) {
try {
return alias == null ? null : ParameterMode.valueOf(alias);
} catch (IllegalArgumentException e) {
throw new BuilderException("Error resolving ParameterMode. Cause: " + e, e);
}
}View on GitHub (pinned to 008069adb1)
Solutions
- Use an exact JdbcType enum constant (VARCHAR, INTEGER, TIMESTAMP, OTHER, ...) matching the case
- For vendor-specific types, map to the closest standard JdbcType or use jdbcType=OTHER with a custom TypeHandler
Example fix
<!-- before -->
#{id,jdbcType=VARCHAR2}
<!-- after -->
#{id,jdbcType=VARCHAR} Defensive patterns
Strategy: validation
Validate before calling
static final Set<String> VALID = Arrays.stream(JdbcType.values()).map(Enum::name).collect(Collectors.toSet());
void check(String jdbcType) { if (!VALID.contains(jdbcType)) throw new IllegalArgumentException(jdbcType); } Prevention
- Use standard JdbcType constant names, exact upper case
- Add a unit test that parses every mapper XML at build time so typos fail CI, not production
When it happens
Trigger: jdbcType="VARCHAR2" (not a JdbcType constant; the correct value is VARCHAR); jdbcType="varchar" lowercase (valueOf is case-sensitive); typos like jdbcType="NUMERIC " with trailing whitespace; a custom jdbcType invented in XML.
Common situations: Hand-writing XML parameter maps; copying Oracle/DB2 native type names into jdbcType attributes; tool-generated mappings using vendor type names.
Related errors
- Error resolving ResultSetType. Cause: {cause}
- Error creating instance. Cause: {cause}
- Error resolving class. Cause: {cause}
- Type {typeHandlerType} is not a valid TypeHandler because it
- Invalid bound statement (not found): {mapperInterface}.{meth
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/6483578535062cfd.
Report an issue: GitHub.