{"record":{"id":"da2f5a761e15793a","repo":"baomidou/mybatis-plus","slug":"not-configure-ikeygenerator-implementation-class","errorCode":null,"errorMessage":"not configure IKeyGenerator implementation class.","messagePattern":"not configure IKeyGenerator implementation class\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java","lineNumber":626,"sourceCode":"     *\n     * @param clazz             反射类\n     * @param annotationHandler 注解处理类\n     * @return 属性集合\n     */\n    public static List<Field> getAllFields(Class<?> clazz, AnnotationHandler annotationHandler) {\n        List<Field> fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz));\n        return fieldList.stream()\n            .filter(field -> {\n                /* 过滤注解非表字段属性 */\n                TableField tableField = annotationHandler.getAnnotation(field, TableField.class);\n                return (tableField == null || tableField.exist());\n            }).collect(toList());\n    }\n\n    public static KeyGenerator genKeyGenerator(String baseStatementId, TableInfo tableInfo, MapperBuilderAssistant builderAssistant) {\n        List<IKeyGenerator> keyGenerators = GlobalConfigUtils.getKeyGenerators(builderAssistant.getConfiguration());\n        if (CollectionUtils.isEmpty(keyGenerators)) {\n            throw new IllegalArgumentException(\"not configure IKeyGenerator implementation class.\");\n        }\n        IKeyGenerator keyGenerator = null;\n        if (keyGenerators.size() > 1) {\n            // 多个主键生成器\n            KeySequence keySequence = tableInfo.getKeySequence();\n            if (null != keySequence && DbType.OTHER != keySequence.dbType()) {\n                keyGenerator = keyGenerators.stream().filter(k -> k.dbType() == keySequence.dbType()).findFirst().orElse(null);\n            }\n        }\n        // 无法找到注解指定生成器，默认使用第一个生成器\n        if (null == keyGenerator) {\n            keyGenerator = keyGenerators.get(0);\n        }\n        Configuration configuration = builderAssistant.getConfiguration();\n        String id = builderAssistant.getCurrentNamespace() + StringPool.DOT + baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;\n        ResultMap resultMap = new ResultMap.Builder(builderAssistant.getConfiguration(), id, tableInfo.getKeyType(), new ArrayList<>()).build();\n        MappedStatement mappedStatement = new MappedStatement.Builder(builderAssistant.getConfiguration(), id,\n            new StaticSqlSource(configuration, keyGenerator.executeSql(tableInfo.getKeySequence().value())), SqlCommandType.SELECT)","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java#L608-L644","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Register a matching IKeyGenerator, e.g. GlobalConfig.DbConfig/dbConfig keyGenerators: add OracleKeyGenerator, PostgreKeyGenerator, or H2KeyGenerator as appropriate","With manual MybatisSqlSessionFactoryBean setup: GlobalConfig globalConfig = new GlobalConfig(); globalConfig.getDbConfig().setKeyGenerators(...)","If you do not want sequence keys, remove @KeySequence and use IdType.AUTO or ASSIGN_ID instead"],"exampleFix":"// before\nMybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();\n// no key generators registered -> error on @KeySequence entity insert\n// after\nGlobalConfig gc = new GlobalConfig();\ngc.getDbConfig().setKeyGenerators(Collections.singletonList(new OracleKeyGenerator()));\nfb.setGlobalConfig(gc);","handlingStrategy":"validation","validationCode":"// At startup, assert sequence support matches your entities\nboolean usesKeySequence = entities.stream().anyMatch(c -> c.isAnnotationPresent(KeySequence.class));\nif (usesKeySequence && CollectionUtils.isEmpty(GlobalConfigUtils.getKeyGenerators(configuration))) {\n    throw new IllegalStateException(\"@KeySequence entities require a registered IKeyGenerator\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register the DB-specific IKeyGenerator (Oracle/PG/H2) whenever any entity uses @KeySequence","Add a startup self-test that inserts one sequence-keyed entity into a test schema","Centralize GlobalConfig setup in one factory bean so data sources cannot miss registration"],"tags":["mybatis-plus","primary-key","sequence","configuration"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}