mybatis/mybatis-3 · error · IllegalStateException
Mapping is missing column attribute for property {}
Error message
Mapping is missing column attribute for property {} What it means
Thrown by ResultMapping.Builder.validate() when a result mapping has no column, no composite columns, and is not backed by a nested resultMap. MyBatis requires a column for every plain mapping because it is the only way to know which JDBC column feeds the property. Only mappings that select into a nested resultMap (nestedResultMapId set) or use composite columns are exempt.
Source
Thrown at src/main/java/org/apache/ibatis/mapping/ResultMapping.java:169
public ResultMapping build() {
// lock down collections
resultMapping.flags = List.copyOf(resultMapping.flags);
resultMapping.composites = List.copyOf(resultMapping.composites);
validate();
return resultMapping;
}
private void validate() {
// Issue #697: cannot define both nestedQueryId and nestedResultMapId
if (resultMapping.nestedQueryId != null && resultMapping.nestedResultMapId != null) {
throw new IllegalStateException(
"Cannot define both nestedQueryId and nestedResultMapId in property " + resultMapping.property);
}
// Issue #4 and GH #39: column is optional only in nested resultMaps but not in the rest
if (resultMapping.nestedResultMapId == null && resultMapping.column == null
&& resultMapping.composites.isEmpty()) {
throw new IllegalStateException("Mapping is missing column attribute for property " + resultMapping.property);
}
if (resultMapping.getResultSet() != null) {
int numColumns = 0;
if (resultMapping.column != null) {
numColumns = resultMapping.column.split(",").length;
}
int numForeignColumns = 0;
if (resultMapping.foreignColumn != null) {
numForeignColumns = resultMapping.foreignColumn.split(",").length;
}
if (numColumns != numForeignColumns) {
throw new IllegalStateException(
"There should be the same number of columns and foreignColumns in property " + resultMapping.property);
}
}
}
public Builder column(String column) {View on GitHub (pinned to 008069adb1)
Solutions
- Add the column attribute: <result property="prop" column="col_name"/>.
- If the value comes from another statement's result map, point at a nested resultMap via resultMap="..." so nestedResultMapId is set.
- For multi-column mappings (e.g. composite keys), supply <constructor>/<id> composites or columnPrefix so composites is non-empty.
- If building programmatically, call builder.column("col_name") before build().
Example fix
<!-- before --> <result property="userName" javaType="string"/> <!-- after --> <result property="userName" column="user_name" javaType="string"/>
Defensive patterns
Strategy: validation
Validate before calling
// before build(): a plain mapping needs a column, composites, or a nested resultMap boolean ok = rm.nestedResultMapId != null || rm.column != null || !rm.composites.isEmpty(); // with the Builder: always call .column(...) for non-nested mappings
Prevention
- Treat column as mandatory when writing <result>/<id> entries unless they point at a nested resultMap.
- Lint mapper XML (e.g. mybatis-generator or a schema-aware validator) in CI to catch missing attributes.
When it happens
Trigger: Building a ResultMapping via new ResultMapping.Builder(configuration, "prop", null, javaType).build(), or an XML resultMap entry like <result property="prop" javaType="..."/> with no column attribute and no nested resultMap select.
Common situations: Hand-writing a resultMap and forgetting the column attribute; using <id>/<result> elements that only carry javaType; programmatically constructing ResultMapping without calling builder.column(...).
Related errors
- Error in result map '{resultMapId}'. We do not support parti
- If there is no type discriminator, then the NamedResultMap a
- Ambiguous collection type for property '{property}'. You mus
- A query was run and no Result Maps were found for the Mapped
- Invalid bound statement (not found): {mapperInterface}.{meth
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/ffdca0dae5267622.
Report an issue: GitHub.