baomidou/mybatis-plus · error · TypeException

Unable to find a usable constructor for %s

Error message

Unable to find a usable constructor for %s

What it means

The configured default enum TypeHandler class exposes neither a constructor taking a Class nor a no-arg constructor, so CompositeEnumTypeHandler.getInstance cannot instantiate it. Both fallback paths (getConstructor(Class.class) and getConstructor()) failed.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/handlers/CompositeEnumTypeHandler.java:96

    }

    @SuppressWarnings("unchecked")
    public <T> TypeHandler<T> getInstance(Class<?> javaTypeClass, Class<?> typeHandlerClass) {
        if (javaTypeClass != null) {
            try {
                Constructor<?> c = typeHandlerClass.getConstructor(Class.class);
                return (TypeHandler<T>) c.newInstance(javaTypeClass);
            } catch (NoSuchMethodException ignored) {
                // ignored
            } catch (Exception e) {
                throw new TypeException("Failed invoking constructor for handler " + typeHandlerClass, e);
            }
        }
        try {
            Constructor<?> c = typeHandlerClass.getConstructor();
            return (TypeHandler<T>) c.newInstance();
        } catch (Exception e) {
            throw new TypeException("Unable to find a usable constructor for " + typeHandlerClass, e);
        }
    }
}

View on GitHub (pinned to bf67d90747)

Solutions

  1. Add a public no-arg constructor and/or a public constructor accepting a single Class argument to the custom handler
  2. Ensure the handler class is public and accessible
  3. If the handler needs configuration, initialize it from the no-arg constructor via a static registry

Example fix

// before
public class MyEnumHandler extends BaseTypeHandler<Enum<?>> {
    public MyEnumHandler(String config) { ... }
}
// after
public class MyEnumHandler extends BaseTypeHandler<Enum<?>> {
    public MyEnumHandler() { this(defaultConfig()); }
    public MyEnumHandler(Class<?> type) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// Startup check for a custom default enum handler
Constructor<?>[] ctors = MyHandler.class.getConstructors();
boolean ok = Arrays.stream(ctors).anyMatch(c -> c.getParameterCount() == 0
        || (c.getParameterCount() == 1 && c.getParameterTypes()[0] == Class.class));
if (!ok) throw new IllegalStateException("Handler needs a public no-arg or (Class) constructor");

Prevention

When it happens

Trigger: defaultEnumTypeHandler points to a class whose only constructors require other parameter types, or the class is non-public/in a non-exported package making getConstructor fail with an access exception.

Common situations: Custom handler with only a (String) or (Properties) constructor; handler class not public; Java module access restrictions blocking reflective constructor access.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/487b153282af9eee. Report an issue: GitHub.