You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 16:25:21