Spring JPA多属性OneToMany关联映射:Parent与Child双向配置问题
JPA双向关联配置:Parent与多Child的双关联场景
由于Child实体同时通过father和mother两个字段关联Parent,这是两个独立的多对一双向关联,而非单一的一对多关联,因此Parent需要分别维护这两个关联的反向集合,具体配置如下:
1. 修改Parent实体
添加两个@OneToMany注解的集合,分别对应该Parent作为父亲和母亲的孩子,mappedBy属性分别指向Child类中的father和mother字段:
@Entity @AllArgsConstructor @NoArgsConstructor @Data public class Parent { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; /* ... */ // 该Parent作为父亲关联的孩子集合 @OneToMany(mappedBy = "father", fetch = FetchType.LAZY) private Collection<Child> fatheredChildren; // 该Parent作为母亲关联的孩子集合 @OneToMany(mappedBy = "mother", fetch = FetchType.LAZY) private Collection<Child> motheredChildren; }
2. Child实体保持原有配置
Child中的father和mother是关联的主控端,负责维护数据库外键(father_id和mother_id),无需修改:
@Entity @AllArgsConstructor @NoArgsConstructor @Data public class Child { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; /* ... */ @ManyToOne @JoinColumn(name = "father_id") private Parent father; @ManyToOne @JoinColumn(name = "mother_id") private Parent mother; }
关键说明
- 不能用单一的
children集合同时对应两个关联,JPA无法区分孩子是通过父亲还是母亲关联到Parent的,会导致关联逻辑混乱。 - 如果需要获取某个Parent的所有孩子(无论作为父亲还是母亲),可以添加一个非持久化的计算属性:
@Transient public Collection<Child> getAllChildren() { Set<Child> allChildren = new HashSet<>(); if (fatheredChildren != null) { allChildren.addAll(fatheredChildren); } if (motheredChildren != null) { allChildren.addAll(motheredChildren); } return allChildren; }
@Transient标记会让JPA忽略该属性,不会将其映射到数据库字段。
内容的提问来源于stack exchange,提问作者galalem
相关产品推荐
相关产品推荐

