mybatis/mybatis-3 · error · ReflectionException
Could not get property '{}' from {}. Cause: {}
Error message
Could not get property '{}' from {}. Cause: {} What it means
BeanWrapper.getBeanProperty invokes the property's read method via reflection. If the getter itself throws (any non-runtime Throwable, unwrapped via ExceptionUtil.unwrapThrowable), MyBatis wraps it in a ReflectionException naming the property, the owner class, and the cause. The real failure is inside the getter's code — the exception message's Cause is the key.
Source
Thrown at src/main/java/org/apache/ibatis/reflection/wrapper/BeanWrapper.java:197
} catch (Exception e) {
throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name
+ "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
}
return metaValue;
}
private Object getBeanProperty(PropertyTokenizer prop, Object object) {
try {
Invoker method = metaClass.getGetInvoker(prop.getName());
try {
return method.invoke(object, NO_ARGUMENTS);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} catch (RuntimeException e) {
throw e;
} catch (Throwable t) {
throw new ReflectionException(
"Could not get property '" + prop.getName() + "' from " + object.getClass() + ". Cause: " + t.toString(), t);
}
}
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
try {
Invoker method = metaClass.getSetInvoker(prop.getName());
Object[] params = { value };
try {
method.invoke(object, params);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} catch (Throwable t) {
throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass()
+ "' with value '" + value + "' Cause: " + t.toString(), t);
}
}View on GitHub (pinned to 008069adb1)
Solutions
- Read the Cause in the exception message and fix the underlying code in the getter (usually an NPE on an unset field)
- Make the getter defensive: return null/default when its dependencies are not initialized
- Avoid referencing computed/logic-heavy getters in mapper expressions; map stored fields instead
- Initialize the fields the getter depends on (constructor or field initializers)
Example fix
// before
public String getFullName() { return firstName.concat(" ").concat(lastName); } // NPE when null
// after
public String getFullName() {
return Stream.of(firstName, lastName).filter(Objects::nonNull).collect(Collectors.joining(" "));
} Defensive patterns
Strategy: try-catch
Try / catch
try {
Object v = metaObject.getValue("fullName");
} catch (ReflectionException e) {
Throwable cause = e.getCause(); // inspect: the getter itself failed
// fix getter defensively; do not blanket-catch and continue in production paths
throw new IllegalStateException("Getter failed for fullName: " + cause, cause);
} Prevention
- Keep getters side-effect free and null-tolerant
- Do not reference computed getters in mapper expressions unless they handle unset state
- Initialize fields that getters depend on
When it happens
Trigger: A getter that dereferences an uninitialized internal field and throws NPE; a getter performing computation/parse (e.g. getFullName() concatenating nulls, getDuration() dividing by zero); a getter throwing a checked exception; mapping a transient/computed property in a resultMap or #{expr} evaluation.
Common situations: Lazy-loading proxies inside getters failing after session close; getters with business logic that break on edge-case state (null fields, empty strings); computed getters referenced in mapper expressions that assume populated state.
Related errors
- There is no getter for property named '{}' in '{}'
- Error creating instance. Cause: {cause}
- Error in result map '{resultMapId}'. Failed to find a constr
- Failed to create a new Configuration instance.
- Cannot get Configuration as factory method [" + this.configu
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/9bee32b9bba4e523.
Report an issue: GitHub.