首页 > 解决方案 > 如何持久化两个对象,但如果它已经存在则只更新一个

问题描述

我基本上有一个包含 Booking、Employee 和 Customer 的预订系统。

我想保留一个 Booking 实体。预订实体有一名员工(将提供服务)和一名客户(为其进行预订)。

我希望能够保留一个预订对象,如果它已经存在,则不会在其中创建员工和/或客户。我如何使用 JPA 和休眠来实现这一点。

我还想保留我拥有的当前架构(Booking 表、Employee 表、Customer 表以及 Booking_customer、Booking_employee 之间的关系表......)

这是预订实体:

@Entity
@Table(name = "bookings")
@EntityListeners(AuditingEntityListener.class)
public class Booking
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "booking_id")
    private Long id;

    @Column(name = "title")
    private String title;

    @Column(name = "description")
    private String description;

    @Column(name = "service")
    private String service;

    @NotNull(message = "status is mandatory")
    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private BookingStatus status;

    @Column(name = "scheduled_at", nullable = false)
    private LocalDateTime scheduledAt;

    @Column(name = "created_at")
    @CreationTimestamp
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    @UpdateTimestamp
    private LocalDateTime updatedAt;

    @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinTable(name = "booking_customer", joinColumns = {@JoinColumn(name = "booking_id")}, inverseJoinColumns = {@JoinColumn(name = "customer_id")})
    private Customer customer;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinTable(name = "booking_employee", joinColumns = {@JoinColumn(name = "booking_id")}, inverseJoinColumns = {@JoinColumn(name = "employee_id")})
    private Employee employee;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinTable(name = "booking_address", joinColumns = {@JoinColumn(name = "booking_id")}, inverseJoinColumns = {@JoinColumn(name = "address_id")})
    private Address address;
}

这是客户实体:

@Entity
@Table(name = "customers")
@EntityListeners(AuditingEntityListener.class)
public class Customer
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "customer_id")
    private Long id;

    @NotBlank(message = "firstName is mandatory")
    @Column(name = "first_name")
    private String firstName;

    @NotBlank(message = "lastName is mandatory")
    @Column(name = "last_name")
    private String lastName;

    @NotBlank(message = "email is mandatory")
    @Column(name = "email_address")
    private String email;

    @NotBlank(message = "phoneNumber is mandatory")
    @Column(name = "phone_number")
    private String phoneNumber;

    @Column(name = "created_at")
    @CreationTimestamp
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    @UpdateTimestamp
    private LocalDateTime updatedAt;

    @OneToMany(mappedBy = "customer", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Booking> bookings;
 }

这是员工实体:

@Entity
@Table(name = "employees")
@EntityListeners(AuditingEntityListener.class)
public class Employee
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "employee_id")
    private Long id;

    @NotBlank(message = "firstName is mandatory")
    @Column(name = "first_name")
    private String firstName;

    @NotBlank(message = "lastName is mandatory")
    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email_address")
    private String email;

    @NotBlank(message = "phoneNumber is mandatory")
    @Column(name = "phone_number")
    private String phoneNumber;

    @Column(name = "created_at")
    @CreationTimestamp
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    @UpdateTimestamp
    private LocalDateTime updatedAt;

    @OneToMany(mappedBy = "employee", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Booking> bookings;

}

为了清楚起见,我删除了 getter 和 setter。

我希望能够通过这样的邮递员与客户和员工进行预订

{
    "title": "Haircut & Beards with Aymen",
    "description": "I would like to clean shave my head",
    "service": "COUPE-12 Haircut",
    "status": "PENDING",
    "scheduledAt": "2021-08-10T15:50:05.609",
    "customer": {
        "firstName": "Raz",
        "lastName": "ari",
        "email": "bena97@gpil.com",
        "phoneNumber": "5149455541"
    },
    "employee": {
        "firstName": "Garcon",
        "lastName": "Mansur",
        "email": "mansur@gmail.com",
        "phoneNumber": "541659898"
    },
    "address": {
        "location": "10424 rue du loili, Montreal, H9P1Z5"
    }
}

大多数时候,预订中的员工实体将是数据库中已经存在的员工,但现在每次我发布这个 JSON 时,它都会在数据库中创建一个新的员工记录。

标签: javaspringhibernatejpa

解决方案


我建议你提供一个实体的 id 字段,hibernate 会自动检查和设置。如果没有,它将创建新记录。但是,如果不可能,请按照@YoManToMero 提到的那样手动检查


推荐阅读