mybatis/mybatis-3 · error · ReflectionException

Cannot get the value '{}' because the property '{}' is null.

Error message

Cannot get the value '{}' because the property '{}' is null.

What it means

When evaluating an indexed property like 'list[0]' or 'map[key]', BaseWrapper.getCollectionValue first resolves the owning property via the MetaObject graph; if that resolved collection object is null, there is nothing to index into, so a ReflectionException is thrown naming the property. It means the container exists in the expression but its value is null at evaluation time.

Source

Thrown at src/main/java/org/apache/ibatis/reflection/wrapper/BaseWrapper.java:47

public abstract class BaseWrapper implements ObjectWrapper {

  protected static final Object[] NO_ARGUMENTS = {};
  protected final MetaObject metaObject;

  protected BaseWrapper(MetaObject metaObject) {
    this.metaObject = metaObject;
  }

  protected Object resolveCollection(PropertyTokenizer prop, Object object) {
    if ("".equals(prop.getName())) {
      return object;
    }
    return metaObject.getValue(prop.getName());
  }

  protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
    if (collection == null) {
      throw new ReflectionException("Cannot get the value '" + prop.getIndexedName() + "' because the property '"
          + prop.getName() + "' is null.");
    }
    if (collection instanceof Map) {
      return ((Map) collection).get(prop.getIndex());
    }
    int i = Integer.parseInt(prop.getIndex());
    if (collection instanceof List) {
      return ((List) collection).get(i);
    } else if (collection instanceof Object[]) {
      return ((Object[]) collection)[i];
    } else if (collection instanceof char[]) {
      return ((char[]) collection)[i];
    } else if (collection instanceof boolean[]) {
      return ((boolean[]) collection)[i];
    } else if (collection instanceof byte[]) {
      return ((byte[]) collection)[i];
    } else if (collection instanceof double[]) {
      return ((double[]) collection)[i];

View on GitHub (pinned to 008069adb1)

Solutions

  1. Initialize the collection field in the parameter object (e.g. private List<Item> items = new ArrayList<>();) so it is never null
  2. Guard the SQL fragment with <if test="items != null"> before referencing items[0]
  3. Ensure upstream code always sets the collection before the statement executes
  4. For Map parameters, put an empty collection under the key instead of leaving it absent/null

Example fix

<!-- before -->
SELECT * FROM t WHERE id = #{items[0].id}  <!-- items is null -->

<!-- after -->
<if test="items != null and items.size() > 0">
  SELECT * FROM t WHERE id = #{items[0].id}
</if>
Defensive patterns

Strategy: validation

Validate before calling

// before running the statement / MetaObject read
Object coll = metaObject.getValue("items");
if (coll == null) {
  // skip indexed access or initialize the collection first
}

Try / catch

try {
  Object v = metaObject.getValue("items[0].id");
} catch (ReflectionException e) {
  if (e.getMessage().contains("is null")) { /* treat as absent value: default/skip */ }
  else throw e;
}

Prevention

When it happens

Trigger: #{items[0].id} in a mapper when the 'items' field of the parameter object is null; MetaObject.getValue("map[key]") when the map property itself is null; resultMap nested mappings indexing into a null List/Map/array property.

Common situations: Parameter DTO where a collection field was never initialized; conditional code that only populates a list in some branches; optional/absent keys in a Map parameter; a query returns null into a field that a subsequent expression indexes.

Related errors


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