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

  1. Add a public no-arg constructor to the nested property type (with Lombok add @NoArgsConstructor)
  2. Initialize the nested property at declaration: private Customer customer = new Customer();
  3. Change the nested property's declared type from interface/abstract to a concrete instantiable class
  4. 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

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


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/6eeb8abc04977de8. Report an issue: GitHub.