Spring数据和Hibernate中的非受控删除

Spring数据和Hibernate中的非受控删除,hibernate,spring-boot,spring-data-jpa,Hibernate,Spring Boot,Spring Data Jpa,我不是Hibernate专家,所以我的问题可能很琐碎 我正在为一个活动编写一个预订引擎。 使用该引擎,可以进行注册,每个注册都有一定数量的参与者。每个注册可以关联一个或多个付款 对于每次登记,可以对房间进行多个预订。预订可以是一个房间的一部分(例如,为两个想要共用一个四人房间的参与者预订),也可以是整个房间。每个房间可以有多个房间布置(例如,四人、三人或双人),对应于特定的房间类型。预订房间时,所选房间类型和房间通过连接到预订的房间分配连接 为了在Spring中编写此代码,我设置了以下模型类:

我不是Hibernate专家,所以我的问题可能很琐碎

我正在为一个活动编写一个预订引擎。 使用该引擎,可以进行注册,每个注册都有一定数量的参与者。每个注册可以关联一个或多个付款

对于每次登记,可以对房间进行多个预订。预订可以是一个房间的一部分(例如,为两个想要共用一个四人房间的参与者预订),也可以是整个房间。每个房间可以有多个房间布置(例如,四人、三人或双人),对应于特定的房间类型。预订房间时,所选房间类型和房间通过连接到预订的房间分配连接

为了在Spring中编写此代码,我设置了以下模型类:

Registration.java

@Entity
@Table(name = "registrations")
@Data
public class Registration {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    // other fields

}
@Entity
@Table(name = "reservations")
@Data
public class Reservation {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_assignment_id")
    private RoomAssignment roomAssignment;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "registration_id")
    private Registration registration;


    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "reservation_id")
    private List<Participant> participants;

    // other fields

}
Participant.java

@Entity
@Table(name = "participants")
@Data
public class Participant {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @ManyToOne(targetEntity = Registration.class)
    @JoinColumn(name = "registration_id")
    private Registration registration;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "reservation_id")
    private Reservation reservation;

    // other fields
}
Reservation.java

@Entity
@Table(name = "registrations")
@Data
public class Registration {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    // other fields

}
@Entity
@Table(name = "reservations")
@Data
public class Reservation {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_assignment_id")
    private RoomAssignment roomAssignment;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "registration_id")
    private Registration registration;


    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "reservation_id")
    private List<Participant> participants;

    // other fields

}
所有模型类都有相应的存储库类,我不会在这里添加它们,因为它们只包含方法名,您可以从代码中看到

我目前正在编写删除注册的程序。为此,我消除所有参与者和所有付款,然后对于每个预订,我查看它是否是相应房间分配的唯一对象,在这种情况下,我也消除房间分配,我消除预订,最后是登记。我用这种方法对这部分进行了编码:

@Override
public void deleteRegistration(Registration registration) {
    // Deleting payments
    paymentRepository.deleteAll(paymentRepository.findByRegistration(registration));

    // Deleting participants
    participantRepository.deleteAll(participantRepository.findByRegistration(registration));

    List<Reservation> reservations = reservationRepository.findByRegistration(registration);
    for (Reservation res : reservations) {
        RoomAssignment assignment = roomAssignmentRepository.findByReservationsContains(res);

        if (reservationRepository.findByRoomAssignment(assignment).size() == 1) {
            reservationRepository.delete(res);

            Room room = roomRepository.findByAssignment(assignment);
            room.setAssignment(null);
            roomRepository.save(room);

            roomAssignmentRepository.delete(assignment);
        } else {
            reservationRepository.delete(res);
        }
    }

    registrationRepository.delete(registration);
}
我试着记录hibernate调用,其中一个对我来说肯定很奇怪

这里我列出了它们和相应的java调用

paymentRepository.deleteAll(此注册没有付款)

participatrepository.deleteAll

select participan0_.id as id1_0_, participan0_.birth_date as birth_da2_0_, participan0_.birth_place as birth_pl3_0_, participan0_.email as email4_0_, participan0_.facebook_profile as facebook5_0_, participan0_.first_name as first_na6_0_, participan0_.first_time as first_ti7_0_, participan0_.food_intolerances as food_int8_0_, participan0_.food_preferences as food_pre9_0_, participan0_.gender as gender10_0_, participan0_.last_name as last_na11_0_, participan0_.other_food_notes as other_f12_0_, participan0_.registration_id as registr13_0_, participan0_.reservation_id as reserva14_0_ from participants participan0_ where participan0_.registration_id=?
delete from participants where id=?
reservationRepository.findByRegistration

select reservatio0_.id as id1_3_, reservatio0_.monday as monday2_3_, reservatio0_.registration_id as registra4_3_, reservatio0_.room_assignment_id as room_ass5_3_, reservatio0_.thursday as thursday3_3_ from reservations reservatio0_ where reservatio0_.registration_id=?
roomAssignmentRepository.findByReservationsContains

select roomassign0_.id as id1_5_, roomassign0_.room_type_id as room_typ2_5_ from room_assignments roomassign0_ where ? in (select reservatio1_.id from reservations reservatio1_ where roomassign0_.id=reservatio1_.room_assignment_id)
select room0_.id as id1_7_0_, room0_.assignment_id as assignme3_7_0_, room0_.room_name as room_nam2_7_0_ from rooms room0_ where room0_.assignment_id=?
reservationRepository.delete

select reservatio0_.id as id1_3_, reservatio0_.monday as monday2_3_, reservatio0_.registration_id as registra4_3_, reservatio0_.room_assignment_id as room_ass5_3_, reservatio0_.thursday as thursday3_3_ from reservations reservatio0_ where reservatio0_.room_assignment_id=?
update participants set reservation_id=null where reservation_id=?
delete from reservations where id=?
update reservations set room_assignment_id=null where room_assignment_id=?
update room_arrangements set room_id=null where room_id=?
roomRepository.FindByaSignment

select room0_.id as id1_7_, room0_.assignment_id as assignme3_7_, room0_.room_name as room_nam2_7_ from rooms room0_ where room0_.assignment_id=?
roomRepository.save

update rooms set assignment_id=?, room_name=? where id=?
roomAssignmentRepository.delete

select reservatio0_.id as id1_3_, reservatio0_.monday as monday2_3_, reservatio0_.registration_id as registra4_3_, reservatio0_.room_assignment_id as room_ass5_3_, reservatio0_.thursday as thursday3_3_ from reservations reservatio0_ where reservatio0_.room_assignment_id=?
update participants set reservation_id=null where reservation_id=?
delete from reservations where id=?
update reservations set room_assignment_id=null where room_assignment_id=?
update room_arrangements set room_id=null where room_id=?
最后一次更新room\u安排设置room\u id=null,其中room\u id=?当然是打破非null约束的SQL更新


经过长时间的准备,问题是:为什么Hibernate要做最后一次更新,因为我没有以任何方式修改任何房间安排?在打电话的那一刻,我正在修改RoomAssignment类,它甚至没有连接到RoomArrangement。

。通过写下这个问题,我意识到,正如我们在意大利所说的,魔鬼在细节中

复制和粘贴互联网上的例子让我错误地诠释了RoomAssignment和RoomAssignment之间的关系

@OneToOne(fetch = FetchType.LAZY, mappedBy = "assignment", cascade = CascadeType.ALL)
    private Room room;
问题与CascadeType有关。当然,所有问题:当我删除作业时,Hibernate也会尝试删除房间,并且在执行此操作时,它会通过清除外键来清除房间类型-这当然会导致错误


我可以接受的教训是:从互联网复制粘贴时要小心:)

可爱。通过写下这个问题,我意识到,正如我们在意大利所说的,魔鬼在细节中

复制和粘贴互联网上的例子让我错误地诠释了RoomAssignment和RoomAssignment之间的关系

@OneToOne(fetch = FetchType.LAZY, mappedBy = "assignment", cascade = CascadeType.ALL)
    private Room room;
问题与CascadeType有关。当然,所有问题:当我删除作业时,Hibernate也会尝试删除房间,并且在执行此操作时,它会通过清除外键来清除房间类型-这当然会导致错误

我可以接受的教训是:从internet复制粘贴时要小心:)