baomidou/mybatis-plus · error · IllegalArgumentException

not configure IKeyGenerator implementation class.

Error message

not configure IKeyGenerator implementation class.

What it means

TableInfoHelper.genKeyGenerator builds a Jdbc3KeyGenerator-style key generator for @KeySequence entities, but no IKeyGenerator implementation is registered in the GlobalConfig. Sequence-based primary keys (IdType.INPUT with @KeySequence, common on Oracle/PostgreSQL/DM) require the application to supply a database-specific IKeyGenerator.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java:626

     *
     * @param clazz             反射类
     * @param annotationHandler 注解处理类
     * @return 属性集合
     */
    public static List<Field> getAllFields(Class<?> clazz, AnnotationHandler annotationHandler) {
        List<Field> fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz));
        return fieldList.stream()
            .filter(field -> {
                /* 过滤注解非表字段属性 */
                TableField tableField = annotationHandler.getAnnotation(field, TableField.class);
                return (tableField == null || tableField.exist());
            }).collect(toList());
    }

    public static KeyGenerator genKeyGenerator(String baseStatementId, TableInfo tableInfo, MapperBuilderAssistant builderAssistant) {
        List<IKeyGenerator> keyGenerators = GlobalConfigUtils.getKeyGenerators(builderAssistant.getConfiguration());
        if (CollectionUtils.isEmpty(keyGenerators)) {
            throw new IllegalArgumentException("not configure IKeyGenerator implementation class.");
        }
        IKeyGenerator keyGenerator = null;
        if (keyGenerators.size() > 1) {
            // 多个主键生成器
            KeySequence keySequence = tableInfo.getKeySequence();
            if (null != keySequence && DbType.OTHER != keySequence.dbType()) {
                keyGenerator = keyGenerators.stream().filter(k -> k.dbType() == keySequence.dbType()).findFirst().orElse(null);
            }
        }
        // 无法找到注解指定生成器,默认使用第一个生成器
        if (null == keyGenerator) {
            keyGenerator = keyGenerators.get(0);
        }
        Configuration configuration = builderAssistant.getConfiguration();
        String id = builderAssistant.getCurrentNamespace() + StringPool.DOT + baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
        ResultMap resultMap = new ResultMap.Builder(builderAssistant.getConfiguration(), id, tableInfo.getKeyType(), new ArrayList<>()).build();
        MappedStatement mappedStatement = new MappedStatement.Builder(builderAssistant.getConfiguration(), id,
            new StaticSqlSource(configuration, keyGenerator.executeSql(tableInfo.getKeySequence().value())), SqlCommandType.SELECT)

View on GitHub (pinned to bf67d90747)

Solutions

  1. Register a matching IKeyGenerator, e.g. GlobalConfig.DbConfig/dbConfig keyGenerators: add OracleKeyGenerator, PostgreKeyGenerator, or H2KeyGenerator as appropriate
  2. With manual MybatisSqlSessionFactoryBean setup: GlobalConfig globalConfig = new GlobalConfig(); globalConfig.getDbConfig().setKeyGenerators(...)
  3. If you do not want sequence keys, remove @KeySequence and use IdType.AUTO or ASSIGN_ID instead

Example fix

// before
MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
// no key generators registered -> error on @KeySequence entity insert
// after
GlobalConfig gc = new GlobalConfig();
gc.getDbConfig().setKeyGenerators(Collections.singletonList(new OracleKeyGenerator()));
fb.setGlobalConfig(gc);
Defensive patterns

Strategy: validation

Validate before calling

// At startup, assert sequence support matches your entities
boolean usesKeySequence = entities.stream().anyMatch(c -> c.isAnnotationPresent(KeySequence.class));
if (usesKeySequence && CollectionUtils.isEmpty(GlobalConfigUtils.getKeyGenerators(configuration))) {
    throw new IllegalStateException("@KeySequence entities require a registered IKeyGenerator");
}

Prevention

When it happens

Trigger: An entity uses @KeySequence (or IdType.INPUT with sequence) while GlobalConfig keyGenerators list is empty — typically because the user did not add an IKeyGenerator implementation (e.g. OracleKeyGenerator/PostgreKeyGenerator) via GlobalConfig#setKeyGenerators or a DbConfig-dependent starter configuration.

Common situations: Switching from MySQL auto-increment to Oracle/PG sequences without registering a key generator; multi-database setups where the generator list is configured only for one data source; custom bootstrapping of MybatisSqlSessionFactoryBean that skips key generator registration.

Related errors


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