4.9 KiB
4.9 KiB
学生考核申请更新主键冲突修复报告
问题描述
现象
在考核申请表单中,对已有数据进行修改后点击保存按钮,调用PUT接口更新数据时出现主键冲突错误:
Duplicate entry '1958434137320771585' for key 'PRIMARY'
错误详情
- 接口:
PUT /assessment/application - 错误类型:
java.sql.SQLIntegrityConstraintViolationException - 错误位置:
XskhAssessmentSelfScoreMapper.insert - 根本原因: 更新操作误用插入逻辑
问题分析
根本原因
在 XskhAssessmentApplicationApprovalServiceImpl.updateSelfScores() 和 updateBonusApprovals() 方法中,更新逻辑存在严重缺陷:
原有错误逻辑:
- 删除所有关联的子表记录
- 重新插入新的记录
问题所在:
- 前端传递的数据包含已存在记录的ID
- 后端删除后重新插入时,由于ID已存在导致主键冲突
- 这种"删除重建"的方式会丢失原有的创建时间、创建人等审计信息
影响范围
- 学生考核自评得分表 (
xskh_assessment_self_score) - 附加分申请表 (
xskh_assessment_bonus_approval)
解决方案
修复策略
采用"智能更新"策略,根据记录ID是否存在决定执行更新或插入操作:
// 如果ID存在,则更新;否则新增
if (selfScore.getId() != null) {
// 更新现有记录
selfScoreMapper.updateById(selfScore);
} else {
// 新增记录
selfScoreMapper.insert(selfScore);
}
具体修改
1. 修复自评得分更新逻辑
文件: XskhAssessmentApplicationApprovalServiceImpl.java
方法: updateSelfScores()
private void updateSelfScores(Long applicationId, List<XskhAssessmentSelfScoreBo> selfScoreList) {
if (selfScoreList != null && !selfScoreList.isEmpty()) {
for (XskhAssessmentSelfScoreBo selfScoreBo : selfScoreList) {
XskhAssessmentSelfScore selfScore = MapstructUtils.convert(selfScoreBo, XskhAssessmentSelfScore.class);
selfScore.setApplicationId(applicationId);
// 如果ID存在,则更新;否则新增
if (selfScore.getId() != null) {
// 更新现有记录
selfScoreMapper.updateById(selfScore);
} else {
// 新增记录
selfScoreMapper.insert(selfScore);
}
}
}
}
2. 修复附加分申请更新逻辑
文件: XskhAssessmentApplicationApprovalServiceImpl.java
方法: updateBonusApprovals()
private void updateBonusApprovals(Long applicationId, List<XskhAssessmentBonusApprovalBo> bonusApprovalList) {
if (bonusApprovalList != null && !bonusApprovalList.isEmpty()) {
for (XskhAssessmentBonusApprovalBo bonusApprovalBo : bonusApprovalList) {
XskhAssessmentBonusApproval bonusApproval = MapstructUtils.convert(bonusApprovalBo,
XskhAssessmentBonusApproval.class);
bonusApproval.setApplicationId(applicationId);
// 如果ID存在,则更新;否则新增
if (bonusApproval.getId() != null) {
// 更新现有记录
bonusApprovalMapper.updateById(bonusApproval);
} else {
// 新增记录,设置默认状态
bonusApproval.setStatus("1"); // 默认待审核状态
bonusApprovalMapper.insert(bonusApproval);
}
}
}
}
修复效果
优势
- 保留审计信息: 不再删除重建,保留原有的创建时间、创建人等字段
- 避免主键冲突: 根据ID存在性智能选择更新或插入操作
- 数据完整性: 确保数据的连续性和完整性
- 性能优化: 避免不必要的删除和插入操作
测试验证
- ✅ 新增考核申请:正常插入新记录
- ✅ 修改考核申请:正常更新现有记录
- ✅ 混合操作:同时包含新增和修改的记录
- ✅ 数据完整性:审计字段正确保留
经验总结
开发规范
- 更新操作原则: 避免"删除重建"模式,优先使用"智能更新"
- ID处理策略: 根据ID存在性决定操作类型
- 审计字段保护: 更新时注意保护创建时间、创建人等审计信息
- 事务完整性: 确保关联数据的更新在同一个事务中
代码审查要点
- 检查更新逻辑是否采用"删除重建"模式
- 验证是否正确处理已存在记录的ID
- 确认审计字段的保留策略
- 测试混合操作场景(新增+修改)
相关文件
- 修复文件:
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhAssessmentApplicationApprovalServiceImpl.java - 涉及表:
xskh_assessment_self_score(学生考核自评得分表)xskh_assessment_bonus_approval(附加分申请表)
- 相关接口:
PUT /assessment/application
修复时间: 2025-08-21
修复人员: AI Assistant
状态: 已完成