Spring Data JPA踩坑记录(@id @GeneratedValue)
问题描述
在使用Spring Data JPA进行开发时,当使用 @Id 和 @GeneratedValue 注解来配置主键时,如果没有正确设置主键生成策略,就有可能会遇到一些奇怪的问题。
问题原因
在JPA规范中,对于主键生成策略,可以通过 @GeneratedValue注解来实现。常见的生成策略包括:
- IDENTITY:由数据库自动生成主键
- SEQUENCE:根据序列生成主键
- TABLE:通过一个特定的表来完成主键生成
- AUTO:自动选择适合自己的主键生成策略
对于没有设置主键生成策略的 @Id 注解,是默认使用 AUTO 生成策略。这种情况下,Hibernate会根据数据库的不同,采用不同的生成策略。如:MySQL使用的是自增长主键,PostgreSQL使用的是序列生成。
如果我们在使用MySQL的时候,使用 @Id 注解,没有设置 @GeneratedValue 生成策略的话,就会导致程序在执行插入操作时报错。
解决方案
针对上述问题,一种解决方案是使用 @GeneratedValue 注解来指定主键生成策略,如:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
其中,strategy 属性用于配置主键生成策略,常见的取值包括 IDENTITY(自增长)、SEQUENCE(序列号)、TABLE(表格)等等。
一些代码示例:
使用SEQUENCE生成主键
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@SequenceGenerator(name = "seq", sequenceName = "seq_user_id", allocationSize = 1)
private Long id;
其中,@Sequence 是生成序列的注解,用来指定生成的规则,name 属性为自定义序列名称,sequenceName 属性为指定数据库中的序列名称。
使用TABLE生成主键
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tableGen")
@TableGenerator(name = "tableGen",
table = "hibernate_sequences",
pkColumnName = "seq_id",
pkColumnValue = "user_id",
valueColumnName = "next_value"
)
private Long id;
其中,@TableGenerator 是生成表格主键的注解,用来指定生成的规则,name 属性为自定义表格名称,table 属性为指定的表格名称,pkColumnName 属性指定存储主键名的列,pkColumnValue 属性指定主键的值,valueColumnName 属性指定存储值的列。
总结
在使用Spring Data JPA时,为了避免上述的主键生成策略问题,建议在使用 @Id 注解时,同时指定 @GeneratedValue 注解,明确指定主键生成策略,以保证程序的稳定性和正确性。对于生成策略的取值,应根据具体情况选择合适的方式。
参考文献
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Data JPA踩坑记录(@id @GeneratedValue) - Python技术站