如何在无auto_increment自增ID场景下使用Spring Boot JPA更新数据
错误原因分析
- 「Field 'id' doesn't have a default value」报错原因:你配置的
@GeneratedValue(strategy = GenerationType.IDENTITY)主键生成策略依赖数据库自增能力,你的数据库id字段未设置auto_increment属性,JPA执行SQL时不会携带id字段,等待数据库生成,触发无默认值报错。 - 「Duplicate entry '0' for key 'PRIMARY'」报错原因:删除主键生成注解后,你的主键是基本数据类型
int,默认值为0。如果是未手动赋值id的新实体,JPA会默认插入id=0的数据,触发主键重复冲突;如果是先查询再更新的场景触发该报错,说明你存在其他未赋值id就调用save()的新增逻辑。
无需原生SQL的解决方法
第一步:修正实体类配置
直接替换你的id字段配置为以下内容:
@Id @Column(name = "id") Integer orderID;
修改点说明:
- 删除
@GeneratedValue注解:非自增主键不需要JPA自动生成主键值 - 把基本类型
int改为包装类型Integer:JPA的save()方法判断新增/更新的逻辑为「主键为null走新增,主键有值走更新」,包装类型默认值为null,避免默认0的冲突问题
第二步:业务逻辑适配
- 你当前的先查询再更新逻辑无需修改:查询返回的实体已经带有id值,调用save()时会自动走update逻辑,不会触发报错
- 如果存在新增实体的场景:由于是业务主键,你需要在调用save()前手动给orderID赋值,值由你的业务规则生成
- 可选优化:在实体类上添加
@DynamicUpdate注解,更新时仅修改你变更的字段,减少SQL执行开销
内容的提问来源于stack exchange,提问作者Mahes
相关产品推荐
相关产品推荐

