mybatis/mybatis-3 · error · ReflectionException
Cannot set value of property '{}' because '{}' is null and c
Error message
Cannot set value of property '{}' because '{}' is null and cannot be instantiated on instance of {}. Cause:{} What it means
When MyBatis sets a nested property like 'customer.name' and 'customer' is null, BeanWrapper.instantiatePropertyValue tries to auto-instantiate the intermediate object via the ObjectFactory before setting into it. If that fails — no no-arg constructor, abstract class/interface, primitive, or the ObjectFactory throws — a ReflectionException wrapping the cause is thrown. The message names the property and the type it tried to create.
Source
Thrown at src/main/java/org/apache/ibatis/reflection/wrapper/BeanWrapper.java:180
if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
return metaClass.hasGetter(name);
}
return metaValue.hasGetter(prop.getChildren());
}
return false;
}
@Override
public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
MetaObject metaValue;
Class<?> type = getSetterType(prop.getName());
try {
Object newObject = objectFactory.create(type);
metaValue = MetaObject.forObject(newObject, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(),
metaObject.getReflectorFactory());
set(prop, newObject);
} 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);View on GitHub (pinned to 008069adb1)
Solutions
- Add a public no-arg constructor to the nested property type (with Lombok add @NoArgsConstructor)
- Initialize the nested property at declaration: private Customer customer = new Customer();
- Change the nested property's declared type from interface/abstract to a concrete instantiable class
- If using a custom ObjectFactory, make sure it can create the type with no arguments
Example fix
// before
@AllArgsConstructor // no default constructor
class Customer { ... }
// after
@AllArgsConstructor
@NoArgsConstructor
class Customer { ... } Defensive patterns
Strategy: validation
Validate before calling
// verify the nested property type is auto-instantiable before setting deep paths
Class<?> t = metaClass.getSetterType("customer");
boolean ok = !t.isInterface() && !Modifier.isAbstract(t.getModifiers())
&& java.util.Arrays.stream(t.getConstructors()).anyMatch(c -> c.getParameterCount() == 0);
if (!ok) { metaObject.setValue("customer", new Customer()); } Type guard
boolean instantiable(Class<?> c) {
return !c.isInterface() && !Modifier.isAbstract(c.getModifiers())
&& java.util.Arrays.stream(c.getConstructors()).anyMatch(x -> x.getParameterCount() == 0);
} Try / catch
try {
metaObject.setValue("customer.name", v);
} catch (ReflectionException e) {
// message contains "cannot be instantiated": pre-create the intermediate object and retry once
if (e.getMessage().contains("cannot be instantiated")) {
metaObject.setValue("customer", new Customer());
metaObject.setValue("customer.name", v);
} else throw e;
} Prevention
- Add @NoArgsConstructor when using Lombok constructors on nested types
- Initialize nested properties at field declaration
- Keep nested property types concrete with public no-arg constructors
When it happens
Trigger: MetaObject.setValue("customer.name", v) where customer is null and Customer has no public no-arg constructor or is abstract/an interface; result mapping into a bean whose nested property type is an interface (e.g. List customization) or a class whose construction fails inside a custom ObjectFactory.
Common situations: DTOs with all-args constructors only (Lombok @AllArgsConstructor without @NoArgsConstructor); immutable nested types; nested property declared as an interface or abstract type; custom ObjectFactory with restrictive creation logic.
Related errors
- Error creating instance. Cause: {cause}
- There is no default constructor for {}
- Error instantiating {} with invalid types ({}) or values ({}
- Error in result map '{resultMapId}'. Failed to find a constr
- Failed to create a new Configuration instance.
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/6eeb8abc04977de8.
Report an issue: GitHub.