Micronaut R2DBC一对多关联:子表未插入父ID问题
问题:Micronaut + R2DBC 一对多关联保存时外键未自动填充
使用Micronaut结合PostgreSQL构建Person与Address的一对多关联,保存包含Address的Person对象时,两者均成功插入数据库,但Address表的person_id字段为空。
解决方案
问题出在关联关系配置缺失,需调整实体注解建立双向关联,让R2DBC自动维护外键:
1. 调整Person类的关联配置
在Person的addresses字段上添加mappedBy属性,明确关联的反向字段,确保级联配置生效。
2. 为Address类添加双向关联字段
添加指向Person的MANY_TO_ONE关联字段,通过@JoinColumn映射到数据库的person_id列,让框架自动填充外键。
修正后的代码
BaseFields类(无修改)
@Data @Introspected @Serdeable @MappedEntity public class BaseFields { @GeneratedValue @Id private Long id; private String note; private String recordType; }
Person类
@Data @Introspected @Serdeable @MappedEntity public class Person extends BaseFields{ private String firstName; private String lastName; private String phoneNumber; @Relation(value = Relation.Kind.ONE_TO_MANY, cascade = Relation.Cascade.ALL, mappedBy = "person") private Set<Address> addresses; }
Address类
@Data @Introspected @Serdeable @MappedEntity public class Address extends BaseFields { private String street; private String street2; private String suite; private String city; private String stateProvince; private String country; private String postalCode; private Boolean active; @Relation(Relation.Kind.MANY_TO_ONE) @JoinColumn(name = "person_id") private Person person; // 若需保留personId字段,可添加@Transient避免重复映射 // @Transient // public Long getPersonId() { // return person != null ? person.getId() : null; // } }
关键说明
- 双向关联是R2DBC自动填充外键的必要条件,单方向
ONE_TO_MANY无法让框架自动将父实体ID设置到子实体中。 @JoinColumn(name = "person_id")必须与数据库外键列名完全匹配。- 级联配置
cascade = Relation.Cascade.ALL确保保存Person时自动保存关联的Address。
验证结果
修改后重新发送请求,数据库中Address记录的person_id会被正确填充为对应的Person ID,返回的JSON结果也会包含完整关联数据。
内容的提问来源于stack exchange,提问作者moff2
相关产品推荐
相关产品推荐

