mybatis/mybatis-3 · error · TypeException

'{}' extends TypeReference but misses the type parameter. Re

Error message

'{}' extends TypeReference but misses the type parameter. Remove the extension or add a type parameter to it.

What it means

TypeReference captures its generic type by walking the superclass chain to find a ParameterizedType. If the chain bottoms out at TypeReference itself without ever passing through a parameterized declaration (a raw subclass like 'class Foo extends TypeReference'), the type argument cannot be captured and this TypeException names the offending class.

Source

Thrown at src/main/java/org/apache/ibatis/type/TypeReference.java:47

 * @author Simone Tripodi
 */
public abstract class TypeReference<T> {

  private final Type rawType;

  protected TypeReference() {
    rawType = getSuperclassTypeParameter(getClass());
  }

  Type getSuperclassTypeParameter(Class<?> clazz) {
    Type genericSuperclass = clazz.getGenericSuperclass();
    if (genericSuperclass instanceof Class) {
      // try to climb up the hierarchy until meet something useful
      if (TypeReference.class != genericSuperclass) {
        return getSuperclassTypeParameter(clazz.getSuperclass());
      }

      throw new TypeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
          + "Remove the extension or add a type parameter to it.");
    }

    return ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
  }

  public final Type getRawType() {
    return rawType;
  }

  @Override
  public String toString() {
    return rawType.toString();
  }

}

View on GitHub (pinned to 008069adb1)

Solutions

  1. Add the type parameter: class MyHandler extends TypeReference<String>
  2. Parameterize every intermediate class in the hierarchy, not just the leaf
  3. If the base extension is accidental (you did not need TypeReference), remove it and implement TypeHandler directly

Example fix

// before
public class IdRef extends TypeReference { } // raw

// after
public class IdRef extends TypeReference<Long> { }
Defensive patterns

Strategy: validation

Validate before calling

void checkTypeReference(Class<?> c) {
  Type sup = c.getGenericSuperclass();
  if (sup instanceof Class && sup == TypeReference.class) {
    throw new IllegalStateException(c.getName() + " extends TypeReference raw — add a type parameter");
  }
}

Type guard

static boolean isParameterizedTypeReference(Class<?> c) {
  return c.getGenericSuperclass() instanceof ParameterizedType;
}

Prevention

When it happens

Trigger: Declaring a raw subclass: class MyHandler extends TypeReference (no <T>); extending a raw intermediate class (class Middle extends TypeReference, then class MyHandler extends Middle); using the handler in a mapper before any type info is resolvable.

Common situations: Copy-pasting BaseTypeHandler subclasses that extend TypeReference-backed bases without adding the type parameter; legacy pre-generics code compiled with raw types after a library upgrade introduced TypeReference.

Related errors


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