前言:做项目的时候,执行SQL语句报了Duplicate entry '33382-1-0' for key xxx异常,后来发现是唯一约束导致,于是乎一通谷歌百度,后来解决了,记录一下。
正文:
代码片段是这样的:
session.createSQLQuery("insert ignore student_task_trace (student_id,task_plan_id,task_plan_reads_options_id,question_count,finish_count,creation_time,modify_time) " +
"select s.id,:taskPlanId,:planReadsOptionsId,:questionCount,0,NOW(),NOW() from student as s where s.clazz_id in :clazzIdList")
.setParameter("taskPlanId", taskPlanId).setParameter("planReadsOptionsId",tproId)
.setParameter("questionCount", count).setParameterList("clazzIdList", clazzIds).executeUpdate();
可以看到涉及到数据库的表是student_task_trace 。
表的结构式这样的:
看的出来不仅主键id做了唯一约束,student_id,task_plan_reads_options,sub_type这三个字段做了联合约束,也就是说这三个不能有相同的另一条数据,所以在遇到相同的数据持久化的时候会报异常。
解决方法:
1.使用ignore关键字,避免重复插入记录可以使用:
insert ignore student_task_trace (student_id,task_plan_reads_options_id,sub_type)
VALUES (111111,51,0)
insert into student_task_trace (student_id,task_plan_reads_options_id,sub_type)
VALUES (111111,51,0)
第一条sql执行的时候如果已有相同数据会返回0;
第二条sql执行的时候如果已有相同数据会返回异常,如图:
2.使用Replace,如果旧记录与新记录有相同的值,则在新记录被插入之前,旧记录被删除,存入新纪录:
REPLACE INTO student_task_trace (student_id,task_plan_reads_options_id,sub_type)
VALUES (111111,51,0)
insert into student_task_trace (student_id,task_plan_reads_options_id,sub_type)
VALUES (111111,51,0)
第一条sql执行的时候如果已有相同数据会返回2,因为删除一条插入一条,主键id会变;
第二条sql执行的时候如果已有相同数据会返回异常;
还有其他的解决方案这里不做说明,如需要可自行谷歌-------“解决数据库唯一约束插入相同数据问题”。