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

Java Spring:子类ManyToOne关联EmbeddedId父类加附加Id保存报null错误

复合主键关联子实体保存空字段问题修复方案

核心原因

你的子实体使用了双@Id声明派生复合主键,但未显式定义主键结构,@MapsId未明确指定映射的主键片段,导致JPA级联保存时仅识别父实体映射的主键部分,直接忽略了已赋值的toyInventory字段,最终抛出字段非空约束报错。
你收到的报错中文翻译为:

SQL完整性约束违反异常:toy_inventory字段不能为空

修复步骤

  1. 新建子实体对应的嵌入式复合主键类,明确主键组成结构,必须实现equals和hashCode方法
@Embeddable
public class AnnualServiceHistoryNonMachinePK implements Serializable {
    // 对应父实体的复合主键
    private AnnualServiceHistoryPK annualServiceHistoryPK;
    // 对应ToyInventory的主键字段
    private Long toyInventoryId;

    // 必须重写equals和hashCode
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AnnualServiceHistoryNonMachinePK that = (AnnualServiceHistoryNonMachinePK) o;
        return Objects.equals(annualServiceHistoryPK, that.annualServiceHistoryPK) && Objects.equals(toyInventoryId, that.toyInventoryId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(annualServiceHistoryPK, toyInventoryId);
    }
    // getter、setter省略
}
  1. 修改子实体的映射配置,明确@MapsId对应的主键片段
@Entity
public class AnnualServiceHistoryNonMachine extends Auditable<String> implements Serializable {
    // 显式声明嵌入式复合主键
    @EmbeddedId
    private AnnualServiceHistoryNonMachinePK id = new AnnualServiceHistoryNonMachinePK();

    // 映射父实体关联,对应主键中的annualServiceHistoryPK部分
    @MapsId("annualServiceHistoryPK")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "year", referencedColumnName = "year")
    @JoinColumn(name = "month", referencedColumnName = "month")
    @JoinColumn(name = "route", referencedColumnName = "route")
    private AnnualServiceHistory annualServiceHistory;

    // 映射ToyInventory关联,对应主键中的toyInventoryId部分
    @MapsId("toyInventoryId")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "toy_inventory", referencedColumnName = "id")
    private ToyInventory toyInventory;

    // 其余属性、getter、setter省略
}
  1. 保存父实体前补全双向关联
    调用save方法前,遍历父实体的子实体列表,给每个子实体手动设置annualServiceHistory属性指向当前父实体,确保关联关系双向绑定,避免JPA无法识别关联。

验证

修改完成后重新执行保存操作,JPA会自动从两个关联字段中获取值填充复合主键,不会再出现toy_inventory字段为空的报错。

内容的提问来源于stack exchange,提问作者Brian Leierzapf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:24:03