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
- 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
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
- 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
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
- %s already contains value for %s
- %s does not contain value for %s
- %s is ambiguous in %s (try using the full name including the
- Should be specified either value() or name() attribute in th
- Cannot use both value() and name() attribute in the @CacheNa
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/da2f5a761e15793a.
Report an issue: GitHub.