Spring boot: executeUpdate raise “Duplicate entry for primary key“

文章讨论了在使用JpaRepository更新已有实体时遇到的Duplicateentryforprimarykey错误,原因是未处理审计字段和乐观锁导致的version字段为null。解决办法是在BeanUtils.copyProperties时排除Null字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

使用Jpa repository save函数去更新已有实体时,会报错:executeUpdate raise “Duplicate entry for primary key”。查找网络资料发现并不应该出现这个错误,Jpa repository在save已实体时如果发现数据库中有既存的主键,那么应该自动更新这个实体而不应该报主键冲突的错误,至此问题陷入了死结…

原因分析

经过仔细排查,发现问题出在了数据拷贝的过程上:

  1. 首先Controller接受前端发来的DTO
  2. 将DTO转化为entity,问题就出在这一步,由于entity是有Audit审计和乐观锁控制的,因此没有created_by、created_date、modified_by、modified_date、version这些字段,而再把DTO转化为entity的过程中只是简单的BeanUtils.copyProperties,因此由DTO转化而来的entity的version字段是null
  3. 使用Jpa repository保存entity的过程中,由于version字段是null,导致写数据时乐观锁保存失败。但是尚没有研究清楚为什么报错是Duplicate entry for primary key而非乐观锁的相关错误,还待后续学习排查。

解决方法

在BeanUtils.copyProperties过程中自定义BeanUtils.copyProperties(entity, entityInDB, CustomBeanUtils.getNullPropertyNames(entity));排除entity中Null字段的拷贝。

这个异常信息 `java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '3' for key 'park.PRIMARY'` 表示在向数据库中插入数据时违反了唯一性约束。具体来说: 1. **异常类型**:这是一个 SQL 完整性约束违反异常,表示在执行 SQL 操作时违反了数据库的完整性约束。 2. **具体原因**:异常信息中的 `Duplicate entry '3' for key 'park.PRIMARY'` 表示尝试插入一个主键值为 '3' 的记录,但主键 'park.PRIMARY' 已经存在这个值。 ### 可能的原因 1. **主键冲突**:尝试插入的主键值已经存在于表中。 2. **数据重复**:数据表中已经存在相同的记录。 ### 解决方法 1. **检查插入数据**:在插入数据前,先查询数据库中是否已经存在相同的主键值。 2. **使用唯一索引**:确保插入的数据不会违反唯一性约束。 3. **自动生成主键**:使用数据库自动生成主键(如自增主键),避免手动插入重复主键值。 ### 示例代码 ```java try { // 假设使用 JDBC 进行数据库操作 String sql = "INSERT INTO park (id, name) VALUES (?, ?)"; PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setInt(1, 3); pstmt.setString(2, "Example Park"); pstmt.executeUpdate(); } catch (SQLIntegrityConstraintViolationException e) { // 处理异常,例如记录日志或提示用户 System.out.println("主键冲突,插入失败: " + e.getMessage()); } ``` ### 总结 这个异常通常是由于主键冲突引起的,需要在插入数据前进行数据验证,或者使用数据库自动生成主键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值