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,问题解决。。。

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

你可能感兴趣的:(Springboot和JPA框架下 @GeneratedValue 自增长主键重置问题)