mybatis/mybatis-3 · error · BuilderException
Error resolving JdbcType. 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.
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 creating instance. Cause
- Error resolving class. Cause
- Error resolving ResultSetType. Cause
- Type is not a valid TypeHandler because it does not…
- A query was run and no Result Maps were found for the…
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/6483578535062cfd.
Report an issue: GitHub.
Appendix: 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)