背景
项目为多module项目,分为注册中心服务,和后端服务,后端服务中接收到用户导入数据,保存至本身的数据库中,并调用注册中心服务的接口,将数据同步传给注册中心服务保存。注册中心保存用户数据使用的是hibernate+jpa自带的save方法
报错详情用户导入第一次导入时成功,第二次导入相同用户数据时就会报错(设定是用户没有就新增,有就根据ID更新数据)
2020-11-25 11:25:20.536 ERROR 1748 --- [nio-8089-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : 错误: 重复键违反唯一约束"idx_icdc_user_customer"
详细:键值"(user_id, customer_id)=(Jack, 4429835a-06be-45b9-b82b-4b0077e265c4)" 已经存在
2020-11-25 11:25:20.538 ERROR 1748 --- [nio-8089-exec-3] c.j.i.c.ControllerExceptionHandler : could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
解决
网上搜索了很多信息都是因为主键重复导致的,但排查了我的情况肯定不是因为这样,
反复对比了代码和数据库数据后发现,后端服务中保存的用户数据的ID和注册中心服务中的用户ID不一致,跟踪发现是因为注册中心的User实体类中定义了主键的生成策略,而我传值进去,系统未在数据库中发现与该ID匹配的用户数据,这时候系统并不会采用传值的ID,而是会根据策略生成一个新的ID,所以导致我第二次导入时没有被判别为更新操作,并且又设置了用户名组合唯一,所以导致了报错。
解决办法是将主键生成策略取消,手动生成UUID并赋值 问题解决!