SpringBoot+PostgreSQL中三元多对多关系的实现疑问
三元关联实体配置方案
首先先修正你的Bookings实体中的几个关键问题:
- 移除
@JoinColumn上的insertable = false, updatable = false,否则无法通过Bookings实体维护与另外三个实体的关联关系 - 日期字段建议用
LocalDate而非String,更贴合数据库日期类型的映射规范 - 去掉不必要的
Customer对象初始化操作
修正后的Bookings实体代码:
@Entity(name = "bookings") @Table(name = "bookings") public class Bookings { @Id @SequenceGenerator( name = "bookings_sequence", sequenceName = "bookings_sequence", allocationSize = 1 ) @GeneratedValue( strategy = SEQUENCE, generator = "bookings_sequence" ) @Column(name = "bookings_id", updatable = false) private Long id; @Column(name = "Travel_Start_Date", nullable = false) private LocalDate travelStartDate; @Column(name = "Travel_End_Date", nullable = false) private LocalDate travelEndDate; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "customer_id") private Customer customer; @ManyToOne @JoinColumn(name = "room_id") private Room room; @ManyToOne @JoinColumn(name = "customer_servant_id") private CustomerServant customerServant; // 构造方法、getter/setter 省略 }
接下来在另外三个实体中添加反向关联逻辑,核心是通过@OneToMany绑定到Bookings实体的对应属性:
1. Customer实体
@Entity @Table(name = "customers") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他业务字段... @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true) private Set<Bookings> bookings = new HashSet<>(); // 可选:维护双向关联一致性的辅助方法 public void addBooking(Bookings booking) { bookings.add(booking); booking.setCustomer(this); } public void removeBooking(Bookings booking) { bookings.remove(booking); booking.setCustomer(null); } }
2. Room实体
@Entity @Table(name = "rooms") public class Room { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他业务字段... @OneToMany(mappedBy = "room", cascade = CascadeType.ALL, orphanRemoval = true) private Set<Bookings> bookings = new HashSet<>(); // 可选:维护双向关联一致性的辅助方法 public void addBooking(Bookings booking) { bookings.add(booking); booking.setRoom(this); } public void removeBooking(Bookings booking) { bookings.remove(booking); booking.setRoom(null); } }
3. CustomerServant实体
@Entity @Table(name = "customer_servants") public class CustomerServant { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他业务字段... @OneToMany(mappedBy = "customerServant", cascade = CascadeType.ALL, orphanRemoval = true) private Set<Bookings> bookings = new HashSet<>(); // 可选:维护双向关联一致性的辅助方法 public void addBooking(Bookings booking) { bookings.add(booking); booking.setCustomerServant(this); } public void removeBooking(Bookings booking) { bookings.remove(booking); booking.setCustomerServant(null); } }
核心逻辑说明
三元关联的本质是将原本的关联表升级为独立实体(Bookings),通过@ManyToOne关联三个主实体;每个主实体再通过@OneToMany(mappedBy = "对应属性名")建立反向关联,明确由Bookings实体维护关联关系。可选的辅助方法用于保证双向关联的数据一致性,避免出现游离态实体。
内容的提问来源于stack exchange,提问作者peebee
相关产品推荐
相关产品推荐

