mybatis/mybatis-3 · error · ExecutorException
Constructor auto-mapping of ''{1}'' failed because ''{0}'' w
Error message
Constructor auto-mapping of ''{1}'' failed because ''{0}'' were not found in the result set; Available columns are ''{2}'' and mapUnderscoreToCamelCase is ''{3}''. What it means
Thrown during argument-name-based constructor auto-mapping when at least one column matched and produced a value, but some constructor parameters had no matching column in the result set. The message lists the missing parameter names, the available column names, and the current mapUnderscoreToCamelCase setting, since a name/case/underscore mismatch is the usual cause.
Source
Thrown at src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java:964
constructorArgTypes.add(paramType);
constructorArgs.add(value);
final String mapKey = resultMap.getId() + ":" + columnPrefix;
if (!autoMappingsCache.containsKey(mapKey)) {
constructorAutoMappingColumns.computeIfAbsent(mapKey, k -> new ArrayList<>()).add(columnName);
}
columnNotFound = false;
foundValues = value != null || foundValues;
}
}
if (columnNotFound) {
if (missingArgs == null) {
missingArgs = new ArrayList<>();
}
missingArgs.add(paramName);
}
}
if (foundValues && constructorArgs.size() < params.length) {
throw new ExecutorException(MessageFormat.format(
"Constructor auto-mapping of ''{1}'' failed " + "because ''{0}'' were not found in the result set; "
+ "Available columns are ''{2}'' and mapUnderscoreToCamelCase is ''{3}''.",
missingArgs, constructor, rsw.getColumnNames(), configuration.isMapUnderscoreToCamelCase()));
}
return foundValues;
}
private boolean columnMatchesParam(String columnName, String paramName, String columnPrefix) {
if (columnPrefix != null) {
if (!columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
return false;
}
columnName = columnName.substring(columnPrefix.length());
}
return paramName
.equalsIgnoreCase(configuration.isMapUnderscoreToCamelCase() ? columnName.replace("_", "") : columnName);
}
View on GitHub (pinned to 008069adb1)
Solutions
- Alias the SQL columns to match constructor parameter names exactly: SELECT user_name AS userName.
- Enable mapUnderscoreToCamelCase (<setting name="mapUnderscoreToCamelCase" value="true"/>) if columns are snake_case and parameters camelCase.
- Add the missing column(s) to the SELECT list, or remove/rename the constructor parameter to an existing column.
- Verify the code was compiled with -parameters so parameter names are the real names, not arg0/arg1.
Example fix
// before
// mybatis-config.xml: mapUnderscoreToCamelCase=false
// SELECT id, user_name FROM users
public User(Long id, String userName) { ... } // 'userName' not found
// after
// mybatis-config.xml: <setting name="mapUnderscoreToCamelCase" value="true"/>
// SELECT id, user_name FROM users
public User(Long id, String userName) { ... } Defensive patterns
Strategy: validation
Validate before calling
// after compiling with -parameters, assert every ctor param has a matching column
List<String> cols = ...; // from ResultSetMetaData.getColumnLabels, upper-cased
boolean camel = configuration.isMapUnderscoreToCamelCase();
for (Parameter p : ctor.getParameters()) {
String expected = camel
? Arrays.stream(p.getName().split("(?=[A-Z])")).map(String::toLowerCase).collect(joining("_"))
: p.getName();
if (!cols.contains(expected.toUpperCase(Locale.ENGLISH))) {
throw new IllegalStateException("No column for constructor param '" + p.getName() + "'; columns: " + cols);
}
} Prevention
- Compile with -parameters and keep parameter names equal to column names modulo camelCase.
- Turn mapUnderscoreToCamelCase on project-wide for snake_case schemas instead of per-column aliasing.
- Cover each constructor-mapped query with a test that asserts all fields are populated (a null field hints at partial matching before it becomes an exception).
When it happens
Trigger: argNameBasedConstructorAutoMapping enabled, class compiled with -parameters (or explicit param names), query executed, and a constructor parameter name (after optional underscore-to-camel translation and column prefix stripping via columnMatchesParam) matches no column in rsw.getColumnNames(). Only thrown when foundValues is true, i.e. partial matching succeeded.
Common situations: DB columns use snake_case (user_name) but mapUnderscoreToCamelCase is false and the parameter is userName; column aliases renamed in SQL; SELECT omits one column the constructor declares; parameter renamed in a refactor while the SQL stayed; joined/prefixed result maps where the prefix does not match.
Related errors
- Dots are not allowed in element names, please remove it from
- There was an error configuring JndiDataSourceTransactionPool
- Could not process result for mapping: " + constructorMapping
- 'argNameBasedConstructorAutoMapping' is enabled and the clas
- Constructor auto-mapping of ''{0}'' failed. The constructor
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/6ec664f8ac7fc07a.
Report an issue: GitHub.