JPA一对多关联插入报错:无法将NULL插入EX_LOAN_ID字段
解决JPA OneToMany关联保存时EX_LOAN_ID字段插入NULL的问题
核心问题
你的子类Extensions采用复合主键设计,其中EX_LOAN_ID既是主键的一部分,也是关联父类的外键,但当前映射配置未让Hibernate自动将父类的LOAN_ID同步到子类的exLoanId字段——哪怕你手动赋值,也可能因映射逻辑冲突被Hibernate忽略。
具体修复方案
方案1:给子类外键字段添加@MapsId映射
修改Extensions类,添加父类关联并配合@MapsId让Hibernate自动同步主键值:
public class Extensions implements Serializable { @Id @Column(name = "EX_LOAN_ID") @MapsId("loanId") // "loanId"替换成你父类实体中主键字段的实际名称 private Long exLoanId; @Id @Column(name = "EX_NO") private Long exNo; @Column(name = "EX_EXTENSION_DAYS") private Long exExtensionDays; // 关联父类实体,insertable/updatable设为false避免重复处理字段 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "EX_LOAN_ID", insertable = false, updatable = false) private Loan parentLoan; // Loan替换成你的父类实体类名 }
父类的@OneToMany配置可保留,建议加上orphanRemoval = true维护关联关系完整性:
@OneToMany(targetEntity = Extensions.class, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "EX_LOAN_ID", referencedColumnName = "LOAN_ID") private List<Extensions> extensions;
方案2:抽离复合主键为@Embeddable类(更规范写法)
若复合主键使用场景较多,抽成独立类会让映射逻辑更清晰:
// 复合主键类 @Embeddable public class ExtensionsPK implements Serializable { @Column(name = "EX_LOAN_ID") private Long exLoanId; @Column(name = "EX_NO") private Long exNo; // 必须重写equals和hashCode方法,实现略 }
修改Extensions实体:
public class Extensions implements Serializable { @EmbeddedId private ExtensionsPK id; @Column(name = "EX_EXTENSION_DAYS") private Long exExtensionDays; // 关联父类,通过@MapsId绑定主键中的exLoanId字段 @MapsId("exLoanId") @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "EX_LOAN_ID") private Loan parentLoan; }
注意事项
- 无需手动给
extensions集合里的exLoanId赋值,让Hibernate通过@MapsId自动处理,避免因父类自增主键生成顺序导致的赋值无效问题。 - 若父类主键为自增类型,使用
@MapsId后无需提前保存父类获取ID,Hibernate会自动完成主键同步。
内容的提问来源于stack exchange,提问作者VKP
相关产品推荐
相关产品推荐

