Springboot和JPA框架下 @GeneratedValue 自增长主键重置问题

最近研究了一下java后端框架Springboot,在存储时候使用了JPA,然后坑就来了。。。

数据库存储少不了的就是主键,JPA提供多种主键生成方式,至于怎么用,网上一搜很多。这篇文章主要讲自增主键。

一般自增长的主键直接用@GeneratedValue这个注解就可以,默认就是AUTO的自增主键。

    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

等同于

    @GeneratedValue
    private int id;

这种方式生成的主键就是自增长的。但是问题来了,如果我清空数据库,并且想把主键重置到1开始怎么办?

网上搜索了下,发现MYSQL truncate table_name 可以清空数据库,并且重置主键,OK,试了一下,然后重新添加一条数据,发现。。。。

id还是接着上次清除后的值继续增长!!!!

然后还有说用alter这个方法的,同样不靠谱。。。
没办法,只能drop表重新创建试试了,结果发现。。。依然不好使。。。

事已至此,重建表都不能重置这个ID,说明这个ID应该不是MYSQL能左右的了,因此基本可以断定是JPA框架内部操作的。

检测了一下表中ID的属性,发现Auto Increment并没有被勾选


MYSQL Workbench中查看ID的属性

到此已经定罪了,是JPA的问题。。

翻看了一下JPA主键生成的策略:

  • TABLE:使用一个特定的数据库表格来保存主键。
  • SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
  • IDENTITY:主键由数据库自动生成(主要是自动增长型)
  • AUTO:主键由程序控制。

发现使用IDENTITY这个策略,就是由数据库生成的主键了,因此尝试把注解修改为

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

发现这样就可以通过重置MYSQL的主键来解决问题了。。。到此可以得到一种解决方案。。

当然我们还想知道JPA控制的主键怎么重置。既然这个主键不受表的限制,因此确定不可能是与表同步的数据,然后又检测了一下配置文件,发现也没有设置过相关参数。
最后在数据库中发现了一个叫做 hibernate_sequence 的表

hibernate_sequence

这个表并不是我手动建的,因此应该是Springboot和JPA自行创建的表,打开发现其中只有一个元素:
next_val
数值就是下次插入的ID值。。。
因此尝试修改生成策略为AUTO,drop这个表之后,再次运行程序,重新创建的表中next-val值是1。
重新插入一条数据,ID为1,问题解决。。。

原创文章,转载请注明出处,谢谢合作~
//www.greatytc.com/p/c7bd1cfacd3d

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容