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

升级Spring Boot后PostgreSQL序列nextval远小于表最大ID是什么原因?

问题根因

本质是Spring Boot版本升级带来的Hibernate主键生成策略行为变化,具体分三个阶段解释:

1. 升级后第一个报错的由来

  • Spring Boot 1.5 默认集成的低版本Hibernate没有「实体allocationSize配置与数据库序列increment值一致性校验」逻辑,你没显式写allocationSize时,默认值就是50,因为没有校验逻辑,所以旧版本运行正常。
  • Spring Boot 2 集成的Hibernate 5.2+版本新增了上述校验,你的数据库里X_SEQ序列实际的increment by配置是1,和实体默认的50不匹配,因此触发报错。

2. 序列nextval值远小于表最大ID的原因

Hibernate的GenerationType.SEQUENCE默认启用hi/lo高低位优化算法降低数据库访问频率:

  • 当allocationSize=50时,Hibernate每调用1次nextval('X_SEQ')拿到一个高位值,就可以在本地连续生成50个主键ID(计算规则:高位值 * allocationSize + 低位偏移量,偏移量从0到49循环),用完这50个ID才会再次查序列拿新的高位值。
  • 旧版本运行期间一直用这套逻辑生成ID,所以数据库里X_SEQ的当前值虽然只有2万多,但乘以50后生成的ID已经可以覆盖到千万级,和你表内的最大ID 18917000是匹配的。

3. 改allocationSize=1后报唯一键冲突的原因

你把allocationSize改成1之后,Hibernate会关闭hi/lo优化,每次插入都直接拿nextval('X_SEQ')的返回值当主键,但序列当前返回的2万多的ID,早就被之前的hi/lo算法生成过了,自然会触发唯一键冲突报错。


修复方案

你可以根据业务需求二选一:

  • 方案一:保留allocationSize=1的配置,直接调整数据库序列的起始值到比表最大ID更大即可,执行SQL:
ALTER SEQUENCE X_SEQ RESTART WITH 18917001;
  • 方案二:想要保留hi/lo优化提升插入性能,就把数据库序列的increment by值改成50,实体的allocationSize也保持默认的50即可,不需要调整序列当前值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:36:01