mybatis/mybatis-3 · error · ReflectionException

There is no getter for property named '{}' in '{}'

Error message

There is no getter for property named '{}' in '{}'

What it means

Reflector.getGetInvoker(propertyName) throws when no getter is registered for the property (getMethods map has no entry). MyBatis reads getters when extracting parameter values for #{} placeholders, evaluating OGNL in dynamic SQL, and building cache keys.

Source

Thrown at src/main/java/org/apache/ibatis/reflection/Reflector.java:389

    throw new ReflectionException("There is no default constructor for " + clazz);
  }

  public boolean hasDefaultConstructor() {
    return defaultConstructor != null;
  }

  public Invoker getSetInvoker(String propertyName) {
    Invoker method = setMethods.get(propertyName);
    if (method == null) {
      throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + clazz + "'");
    }
    return method;
  }

  public Invoker getGetInvoker(String propertyName) {
    Invoker method = getMethods.get(propertyName);
    if (method == null) {
      throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + clazz + "'");
    }
    return method;
  }

  /**
   * Gets the type for a property setter.
   *
   * @param propertyName
   *          - the name of the property
   *
   * @return The Class of the property setter
   */
  public Class<?> getSetterType(String propertyName) {
    Class<?> clazz = setTypes.getOrDefault(propertyName, nullEntry).getValue();
    if (clazz == null) {
      throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + clazz + "'");
    }
    return clazz;

View on GitHub (pinned to 008069adb1)

Solutions

  1. Add a standard getter getProperty() (or isProperty for booleans) to the parameter class.
  2. Correct the property name in #{} or the OGNL test expression to match an actual readable property.
  3. For maps, pass a Map parameter instead of a bean, or use @Param names so properties resolve differently.

Example fix

<!-- before -->
<select id="find" parameterType="User">SELECT * FROM t WHERE name = #{name}</select>
class User { private String name; }
<!-- after -->
class User { private String name; public String getName(){return name;} }
Defensive patterns

Strategy: validation

Validate before calling

Reflector ref = new Reflector(User.class);
String[] readable = ref.getGetablePropertyNames(); // every #{prop} / test="prop" must appear here

Type guard

boolean hasGetter(Class<?> c, String prop) {
  return Arrays.asList(new Reflector(c).getGetablePropertyNames()).contains(prop.toUpperCase(Locale.ROOT));
}

Prevention

When it happens

Trigger: Referencing #{prop} in SQL where the parameter object has no getProp()/isProp() accessor; <if test="prop != null"> against a write-only or missing property; property name typo.

Common situations: Parameter DTO missing a getter (field-only access); misspelled placeholder vs. bean property; boolean property referenced as getProp instead of isProp and only the field exists; Lombok @Getter omitted.

Related errors


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