You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate更新时找不到新复合键行的原因及解决方案

问题根源

你遇到的错误核心在于误用了merge方法执行新增操作。Hibernate的merge()方法设计目的是合并已存在于数据库中的实体修改——它会先根据传入实体的主键去数据库查找对应记录,找不到就会抛出你看到的"No row with the given identifier exists"错误。而你要添加的是全新的关联记录,merge的逻辑完全不匹配这个场景。

解决步骤
  1. 替换持久化方法
    把DAO中调用merge()的代码换成persist()或save(),这两个方法才是用来持久化新实体的:

    // 原错误代码
    // session.merge(lifterRecord);
    
    // 正确新增代码二选一
    session.persist(lifterRecord); // 推荐,仅用于新实体
    // 或
    session.save(lifterRecord); // 返回生成的主键,兼容新/旧实体
    
  2. 确保关联实体已持久化
    你的LifterRecord依赖复合主键PersonalRecord_LifterID,其中关联的Lifter和PersonalRecord必须是已持久化状态(即已经在数据库中有对应记录)。如果是新创建的Lifter或PersonalRecord,要先调用save/persist把它们存入数据库,再关联到LifterRecord中。

  3. 检查复合主键的equals/hashCode实现
    确保PersonalRecord_LifterID类正确重写了equals()和hashCode()方法,Hibernate依赖这两个方法判断主键是否唯一。示例实现:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PersonalRecord_LifterID that = (PersonalRecord_LifterID) o;
        return Objects.equals(lifterId, that.lifterId) &&
               Objects.equals(personalRecordId, that.personalRecordId);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(lifterId, personalRecordId);
    }
    
  4. 区分新增与更新逻辑
    在DAO层拆分方法,明确saveLifterRecord()(新增)和updateLifterRecord()(更新已存在记录),避免混用方法导致逻辑错误。

内容的提问来源于stack exchange,提问作者Manolo Viso Romero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:42:18