HRPayroll审计表主键重复问题:Excel上传保存失败求助
解决HRPayroll_AUD审计表主键重复导致的批量插入报错问题
问题现象
上传Excel文件时数据读取正常,但保存阶段触发报错:
NOT UPLOADED BECAUSE (conn=4254387) Duplicate entry '1097894' for key 'PRIMARY' ; EXCEPTION OCCURED ON ROW NO. 2
HRPayroll表新增的2条数据主键(310、311)生成正常,但对应的HRPayroll_AUD审计表两条条目使用了相同的主键ID,触发唯一键冲突。
关键信息分析
从Session会话日志可见,两条HRPayRoll_AUD的插入操作共用了同一个DefaultRevisionEntity(id=1097891),说明同一事务内的审计操作复用了版本记录;同时审计表主键重复,核心原因集中在主键生成策略或审计配置异常。
解决方案
1. 修正批量保存代码的错误操作
原代码中在session.save(lTHr)前调用session.evict(lTHr),会将实体从持久化上下文移除,导致Hibernate无法正确追踪实体状态变化,进而干扰审计记录的生成逻辑。移除该操作即可避免状态追踪异常:
@Override public String pushToDB(List<Entity> pEntityList) throws SystemException { logger.entry(); Session session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); String filestatus = ""; int j = 0; try { for (Iterator<Entity> it = pEntityList.iterator(); it.hasNext();) { HrPayRoll lTHr = (HrPayRoll) it.next(); j++; // 移除session.evict(lTHr),避免实体提前脱离持久化上下文 session.save(lTHr); if (j % 300 == 0) { session.flush(); session.clear(); } } tx.commit(); filestatus = "PROCESSED SUCCESSFULLY"; } catch (HibernateException e) { if (tx != null) { tx.rollback(); } filestatus = "NOT UPLOADED BECAUSE " + e.getCause().getMessage() + " ; EXCEPTION OCCURED ON ROW NO. " + j; return filestatus; } finally { if (session != null && session.isOpen()) { session.close(); } } logger.exit(); return filestatus; }
2. 检查审计表与实体的主键配置
- 复合主键场景(Envers默认):确认HRPayRoll_AUD表的主键为复合键(
hrid+REV),且该组合在数据库中设置为唯一约束。若为自定义审计实体,需确保@EmbeddedId或@IdClass配置正确,保证两个字段的组合唯一性。 - 单一主键场景:如果审计表使用单一自增主键,需检查:
- 数据库表中主键字段是否开启自增属性(如MySQL的
AUTO_INCREMENT); - 审计实体的主键注解是否正确,例如使用
@GeneratedValue(strategy = GenerationType.IDENTITY)确保Hibernate能获取数据库生成的唯一主键。
- 数据库表中主键字段是否开启自增属性(如MySQL的
3. 验证审计配置逻辑
- 若使用Hibernate Envers做审计,确认HRPayRoll实体上的
@Audited注解配置正确,未修改默认的审计版本生成逻辑; - 测试单条数据插入:分别插入两条HRPayRoll数据,检查HRPayRoll_AUD表的主键是否唯一,排查是否仅批量操作时出现异常。
内容的提问来源于stack exchange,提问作者Jyoti Pandey
相关产品推荐
相关产品推荐

