ORA-01400报错:JPA双向一对多带复合主键时插入子表外键缺失问题
问题根因定位
1. @MapsId映射字段不存在
你在Ewp类的@ManyToOne关联上标注了@MapsId("e_modelid"),但子表复合主键类EwpPk里根本没有名为e_modelid的字段,JPA无法将父表Eap的主键值同步到子表的复合主键中,导致插入时外键关联字段无值。
2. 注解拼写错误
@joinColumns首字母小写,正确JPA注解为@JoinColumns,拼写错误导致JPA无法识别你的外键字段映射配置,关联规则失效。
3. 双向关联未维护子端父对象引用
双向一对多场景下,仅把Ewp对象添加到父表Eap的ewpList中是不够的,必须手动给每个子表Ewp的eap属性赋值绑定父表对象,否则子表无法获取父表主键值用于外键填充。
4. 其他语法错误
EwpPk类中private Long sid漏写分号- 父表类中
private list<Ewp> ewpList的List首字母小写,不符合Java语法规范
修复方案
第一步:调整子表复合主键类,增加父表主键映射字段
你需要把父表Eap的复合主键整体作为EwpPk的一个属性,用于@MapsId绑定:
@Embeddable public class EwpPk implements Serializable { private static final long serialVersionUID = -3231628074628968344L; @Column(name = "ewp_sid", nullable = false) private Long sid; // 新增父表主键字段,用于@MapsId映射 private EapPk eModelId; @Column(name = "PRTN_KEY", nullable = false) private Date partitionDate; @Column(name = "SUB_PRTN_SEQ_NUM", nullable = false) private int sequenceNumber; // 补充getter、setter、equals、hashcode方法 }
第二步:修正Ewp类的关联注解
@Table(name = "EWP") public class Ewp implements Serializable { private static final long serialVersionUID = 7232535288636665348L; @EmbeddedId private EwpPk modelid; @ManyToOne(targetEntity = Eap.class) // 映射到EwpPk里的eModelId字段 @MapsId("eModelId") // 修正注解首字母大写 @JoinColumns({ @JoinColumn(name="eap_sid", nullable=false, referencedColumnName = "Eap_sid"), @JoinColumn(name="PRTN_KEY", nullable=false, referencedColumnName = "PRTN_KEY"), @JoinColumn(name="SUB_PRTN_SEQ_NUM", nullable=false, referencedColumnName = "SUB_PRTN_SEQ_NUM") }) private Eap eap; // 补充getter、setter方法 }
第三步:修正父表类语法错误
@Table(name = "EAP") public class EnrolledAccountRangePartitionedModel implements Serializable { private static final long serialVersionUID = 700193113967839613L; @EmbeddedId private EapPk e_modelid; // 修正List首字母大写 @OneToMany(targetEntity = Ewp.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER, mappedBy = "eap") private List<Ewp> ewpList; // 补充getter、setter方法 // 建议封装关联关系维护方法,避免手动赋值遗漏 public void addEwp(Ewp ewp) { ewpList.add(ewp); ewp.setEap(this); } }
第四步:保存数据时使用封装的关联方法维护关系
// 示例保存逻辑 Eap eap = new Eap(); // 赋值eap的主键、其他属性 Ewp ewp = new Ewp(); // 赋值ewp自身的sid等属性 // 调用父表的add方法自动维护两边关联 eap.addEwp(ewp); // 保存父表,级联保存子表 eapRepository.save(eap);
内容的提问来源于stack exchange,提问作者retrx22
相关产品推荐
相关产品推荐

