You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate GenerationType.IDENTITY重启后ID跳增20问题求助

问题分析与解决方案

问题根源

你使用的GenerationType.IDENTITY在部分数据库(比如PostgreSQL)底层是基于序列实现的,Hibernate默认会预缓存20个序列值做性能优化——重启应用后,未使用的缓存值会直接丢弃,导致ID跳转到下一个缓存段(比如首次用了1-3,剩下17个没用到,重启后就从21开始)。你尝试的spring.jpa.properties.hibernate.id.new_generator_mappings=false是针对旧版生成器的配置,对IDENTITY模式下的序列缓存无效。

具体解决方案

针对PostgreSQL(IDENTITY底层依赖序列)

方式1:全局修改序列缓存大小

在application.properties或application.yml中添加配置,强制所有序列每次只预取1个ID:

spring.jpa.properties.hibernate.id.optimizer.pooled.preferred_pool_size=1

方式2:实体类显式指定序列规则

直接替换IDENTITY为SEQUENCE生成策略,手动设置增量步长为1:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_entity_seq")
@SequenceGenerator(
    name = "your_entity_seq",
    sequenceName = "your_entity_id_seq",
    initialValue = 1,
    allocationSize = 1
)
@Column(unique = true, nullable = false)
private Long id;

针对MySQL(依赖auto_increment)

MySQL的auto_increment默认不会出现固定跳20的情况,若确实存在问题,按以下步骤排查:

  1. 检查自增配置是否正常:
SHOW VARIABLES LIKE 'auto_increment%';

确保auto_increment_increment和auto_increment_offset的值都是1。
2. 若配置异常,执行以下SQL修改(需重启MySQL永久生效):

SET GLOBAL auto_increment_increment=1;
SET GLOBAL auto_increment_offset=1;

同时在MySQL配置文件(my.cnf/my.ini)中添加:

auto_increment_increment = 1
auto_increment_offset = 1

通用禁用预缓存方案

如果不想修改实体注解,可通过全局配置关闭Hibernate的序列预缓存:

spring.jpa.properties.hibernate.id.optimizer.pooled.loose=false
spring.jpa.properties.hibernate.id.optimizer.pooled.preferred_pool_size=1

注意事项

  • 设置增量步长为1会牺牲部分插入性能(每次插入都要去数据库获取序列值),高并发场景下不建议强制追求连续ID。
  • 生产环境中,ID跳号是常见的性能优化手段,除非业务强依赖连续ID,否则无需修改。

内容的提问来源于stack exchange,提问作者Ranjithkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:15:32