Spring Boot JPA配置@Id主键指定自增起始值步长及相关报错解决
问题原因与解决步骤
1. 优先解决启动报错
你遇到的启动失败最根本的原因是代码中使用了GenericGenerator、Parameter注解但未导入对应的依赖类,导致编译不通过。
根据你使用的Hibernate版本导入对应包即可:
- Hibernate 5.x版本导入:
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter;
- Hibernate 6.x版本
GenericGenerator已标记为废弃,推荐直接使用标准JPA的@SequenceGenerator,无需导入上述两个类。
2. 正确配置自定义主键自增规则(起始值1000、步长10)
提供两种兼容不同场景的配置方案:
方案1:标准JPA@SequenceGenerator(通用所有支持序列的数据库,推荐)
以Reader实体类为例,修改主键配置如下:
@Data @AllArgsConstructor @NoArgsConstructor @ToString @Entity public class Reader { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "reader_seq") @SequenceGenerator( name = "reader_seq", // 生成器名称,和@GeneratedValue的generator对应 sequenceName = "reader_id_seq", // 数据库中生成的序列名 initialValue = 1000, // 主键起始值 allocationSize = 10 // 步长 ) private Long id; private String name; @OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "reader_id") private List<Book> myBooks = new ArrayList<>(); public void addBook(Book book) { myBooks.add(book); } public void removeBook(Book book) { myBooks.remove(book); } }
Book实体类同理配置:
@Data @AllArgsConstructor @NoArgsConstructor @ToString @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_seq") @SequenceGenerator( name = "book_seq", sequenceName = "book_isbn_seq", initialValue = 1000, allocationSize = 10 ) private Long isbn; private String title; @ManyToOne @JsonIgnore private Reader reader; }
最后在application.yml中补充JPA配置,保证Hibernate序列生成逻辑和数据库对齐:
spring: jpa: hibernate: ddl-auto: update # 开发环境会自动创建对应序列,生产环境建议改为none手动维护 properties: hibernate: id: optimizer: pooled: prefer_sequence_per_entity: true
方案2:Hibernate专属@GenericGenerator(兼容Hibernate 5.x、低版本MySQL)
如果使用Hibernate 5.x且数据库不支持标准序列,可以用该方案:
@Id @GeneratedValue(generator = "custom_id_gen") @GenericGenerator( name = "custom_id_gen", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = { @Parameter(name = "initial_value", value = "1000"), @Parameter(name = "increment_size", value = "10"), @Parameter(name = "optimizer", value = "pooled-lo") } ) private Long id;
3. 注意事项
- 如果项目之前已经运行过并生成了旧的表/序列,需要先手动删除旧序列,或者修改旧序列的起始值为1000,否则配置不会生效
- 配置中的步长
allocationSize必须和数据库序列的步长保持一致,否则会出现主键重复、跳跃的问题
内容的提问来源于stack exchange,提问作者AdelLinux80s
相关产品推荐
相关产品推荐

