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
- Add a public no-arg constructor and/or a public constructor accepting a single Class argument to the custom handler
- Ensure the handler class is public and accessible
- 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
- Give custom TypeHandlers a public no-arg constructor by convention
- Add an architecture test (ArchUnit/reflective check) enforcing constructor shape on handler classes
- Document required constructor shapes when introducing custom handler SPIs
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
- Type argument cannot be null
- Failed invoking constructor for handler %s
- Type argument cannot be null
- Failed to create a new Configuration instance.
- Unable to retrieve the mapperInterface and sqlSession proper
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/487b153282af9eee.
Report an issue: GitHub.