baomidou/mybatis-plus · error · TypeException

Failed invoking constructor for handler %s

Error message

Failed invoking constructor for handler %s

What it means

CompositeEnumTypeHandler fell back to the configured default enum TypeHandler (a class taking a Class constructor), and invoking that constructor threw an exception (found via getConstructor(Class.class), but newInstance failed). The handler class exists but its constructor rejected the enum type.

Source

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

    public E getResult(ResultSet rs, int columnIndex) throws SQLException {
        return delegate.getResult(rs, columnIndex);
    }

    @Override
    public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return delegate.getResult(cs, columnIndex);
    }

    @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. Inspect the nested cause to see why the handler constructor threw for the specific enum type
  2. Make the custom handler tolerate plain enums (fall back internally to default behavior) instead of throwing
  3. Annotate the enum correctly (e.g. add @EnumValue field or implement IEnum) if the handler requires it
  4. Restrict the custom handler to the enum types it actually supports

Example fix

// before
public class StatusTypeHandler extends BaseTypeHandler<Enum<?>> {
    public StatusTypeHandler(Class<?> type) {
        if (!type.isAnnotationPresent(Supported.class)) throw new IllegalArgumentException();
    }
}
// after
public class StatusTypeHandler extends BaseTypeHandler<Enum<?>> {
    public StatusTypeHandler(Class<?> type) { /* tolerant: handle unsupported types gracefully */ }
}
Defensive patterns

Strategy: try-catch

Try / catch

try { CompositeEnumTypeHandler.setDefaultEnumTypeHandler(MyHandler.class); } catch (TypeException e) { log.error("Default enum handler unusable: {}", e.getCause()); throw e; } // fail fast at config time, not per query

Prevention

When it happens

Trigger: GlobalConfig/defaultEnumTypeHandler is set to a custom TypeHandler whose (Class) constructor throws — e.g. it only supports certain enum shapes (requires IEnum or @EnumValue annotations) and throws for plain enums.

Common situations: A custom defaultEnumTypeHandler that assumes annotated enums (MybatisEnumTypeHandler-like behavior) but is registered for all enums including plain ones; handler constructor performing lookups that fail for some enum types.

Related errors


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