mybatis/mybatis-3 · error · ReflectionException

Error parsing property name '{}'. Didn't start with 'is', '

Error message

Error parsing property name '{}'.  Didn't start with 'is', 'get' or 'set'.

What it means

MyBatis's Reflector only treats accessor methods whose names start with 'is', 'get' or 'set' as bean property accessors. PropertyNamer.methodToProperty strips that prefix to derive the property name; when a method name has none of these prefixes there is no property name to derive, so a ReflectionException is thrown. In normal flow Reflector filters candidates through PropertyNamer.isProperty first, so hitting this usually means methodToProperty was called directly or a custom Reflector/ObjectWrapper fed it an unfiltered method.

Source

Thrown at src/main/java/org/apache/ibatis/reflection/property/PropertyNamer.java:37

import org.apache.ibatis.reflection.ReflectionException;

/**
 * @author Clinton Begin
 */
public final class PropertyNamer {

  private PropertyNamer() {
    // Prevent Instantiation of Static Class
  }

  public static String methodToProperty(String name) {
    if (name.startsWith("is")) {
      name = name.substring(2);
    } else if (name.startsWith("get") || name.startsWith("set")) {
      name = name.substring(3);
    } else {
      throw new ReflectionException(
          "Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
    }

    if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {
      name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
    }

    return name;
  }

  public static boolean isProperty(String name) {
    return isGetter(name) || isSetter(name);
  }

  public static boolean isGetter(String name) {
    return name.startsWith("get") && name.length() > 3 || name.startsWith("is") && name.length() > 2;
  }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Ensure only names passing PropertyNamer.isProperty(name) (i.e. isGetter/isSetter per the class's own rules) reach methodToProperty
  2. Rename the method in your bean to follow JavaBean conventions (getX/setX/isX) if it is meant to be a property accessor
  3. If you call methodToProperty directly, guard with isProperty() first (note: isProperty excludes Object getClass and ObjectStream can equals methods)
  4. Debug which method name is passed in and fix the caller that bypassed the filter

Example fix

// before
String prop = PropertyNamer.methodToProperty(method.getName()); // throws for "toString"

// after
if (PropertyNamer.isProperty(method.getName())) {
  String prop = PropertyNamer.methodToProperty(method.getName());
}
Defensive patterns

Strategy: validation

Validate before calling

String prop;
if (org.apache.ibatis.reflection.property.PropertyNamer.isProperty(method.getName())) {
  prop = org.apache.ibatis.reflection.property.PropertyNamer.methodToProperty(method.getName());
} else {
  // not an accessor; skip or handle
}

Try / catch

try {
  String prop = PropertyNamer.methodToProperty(name);
} catch (ReflectionException e) {
  // log the offending method name and skip it; do not retry
}

Prevention

When it happens

Trigger: Calling PropertyNamer.methodToProperty("someMethod") or any name not starting with is/get/set; a custom Reflector implementation that passes all methods (not just isProperty()-filtered ones) into methodToProperty; a custom ObjectWrapper or plugin that resolves property names from arbitrary method names.

Common situations: Extending MyBatis reflection (custom wrappers, frameworks built on Reflector); upgrading MyBatis versions where Reflector method filtering changed; unit tests invoking PropertyNamer directly.

Related errors


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