保存父实体时子表外键未自动填充问题求助
我现在遇到一个JPA关联实体的问题,情况是这样的:
- 有两个实体,父实体的主键是子实体的外键
- 保存父实体的时候,子实体对应的外键字段没有自动设置上,想请教大家这是为什么,该怎么解决?
父实体 ExcpType.java
@Getter @Setter @Entity @Table(name = "mst_excp_type") public class ExcpType implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "mst_excp_type_id",columnDefinition = "bigint", unique = true, nullable = false) @GeneratedValue(strategy=GenerationType.IDENTITY) protected Integer mstExcpTypeId; @Column(name = "type_id") protected String typeId; @Column(name = "excp_type_desc") protected String excpTypeDesc; @Column(name = "status") protected String status; @Column(name = "sequence") protected Integer sequence; // 原代码未贴全,推测缺少与子实体的关联配置 }
首先得说,这种情况大概率是实体间的关联关系没配置到位,JPA不会凭空自动识别外键,得咱们明确告诉它关联规则才行。我给你列几个最常见的坑和解决办法:
父实体缺失对子实体的关联配置
你贴的父实体代码里完全没看到和子实体的关联注解。如果是一对多关系,父实体里得加上类似这样的代码:@OneToMany(mappedBy = "excpType", cascade = CascadeType.ALL, orphanRemoval = true) private List<ChildEntity> childEntities = new ArrayList<>();这里
mappedBy的值要和子实体里引用父实体的字段名一致,cascade = CascadeType.ALL会让保存父实体时自动同步保存子实体,同时把父主键赋值给子外键。子实体的外键字段未正确关联父实体对象
子实体不能只存一个普通的Integer mstExcpTypeId字段,得有父实体的引用并标记关联注解,比如:@ManyToOne @JoinColumn(name = "mst_excp_type_id") // name要和子表的外键列名完全匹配 private ExcpType excpType;要是只存数值字段,JPA根本不知道这是外键,自然不会自动填充。
保存时未将子实体与父实体关联绑定
就算注解配全了,要是你只创建了父子对象,却没把子实体加到父实体的关联集合里,JPA也不会帮你关联。正确的保存逻辑应该是这样的:ExcpType parent = new ExcpType(); // 设置父实体的属性值 ChildEntity child = new ChildEntity(); // 设置子实体的其他属性 parent.getChildEntities().add(child); child.setExcpType(parent); // 双向关联最好同时设置两边,避免数据不一致 excpTypeRepository.save(parent);主键生成策略的小细节
你的父主键用的是GenerationType.IDENTITY(数据库自增),保存时父主键是数据库生成后才赋值给对象的。如果保存前你手动给子实体的外键设了父的mstExcpTypeId(这时还是null),肯定会出问题,但只要关联配置正确,JPA会在父主键生成后自动帮子实体填外键,这个不用额外操心。
总结一下:先把两个实体的关联注解补全,双向关联要确保两边都配置好,保存时记得把父子对象绑定起来,这样JPA就能自动维护外键啦。
备注:内容来源于stack exchange,提问作者Sarang S.

