mybatis/mybatis-3 · error · ReflectionException

Cannot get the value

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.

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.

Appendix: 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)