Нарушение ограничения ссылочной целостности при удалении во многих отношениях - PullRequest
0 голосов
/ 24 марта 2020

Получение этого исключения

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKrtt5rijo65gon4wgqj4pv44hj: PUBLIC.user_order FOREIGN KEY(order_id) REFERENCES PUBLIC.""order""(id) (1)"; SQL statement:
delete from "order" where "id"=?

со следующей настройкой:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract @Data class User {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "user_order",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "order_id"))
    private Set<Order> orders = new HashSet<>();
}
@EqualsAndHashCode(callSuper = true)
@Entity
public @Data class Client extends User {
// just fields
}
@EqualsAndHashCode(callSuper = true)
@Entity
public @Data class Worker extends User {
// just fields
}
@Entity
public @Data class Order {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany(mappedBy = "orders")
    @ToString.Exclude @EqualsAndHashCode.Exclude // this is due to a lombok specific stackOverFlow 
    private Set<User> users = new HashSet<>();
}

Когда я гуглил это, и каждая проблема была из-за неправильного набора Что касается отношений, я трижды проверил все, и это выглядит правильно для меня, и когда я проверяю сгенерированные таблицы, все так, как я хотел. Но все же, когда я пытаюсь удалить заказ, я получаю упомянутое исключение. Любые подсказки, почему?

У меня есть данные init по контексту refre sh, если это полезно:

        Worker workerA = (Worker) new Worker().setSalary(BigDecimal.ZERO).setRole(Role.USER).setName("Kate")
                                              .setLastName("Park").setPassword(encoder.encode("123"))
                                              .setUsername("immkath").setFatherName("Andrii")
                                              .setPhone("+38(066) 207 0746");

        Worker workerB = (Worker) new Worker().setSalary(BigDecimal.TEN).setRole(Role.ADMIN).setName("Dar")
                                              .setLastName("Poz").setPassword(encoder.encode("123"))
                                              .setUsername("dpozinen").setFatherName("Andrii")
                                              .setPhone("+38(050) 385 0660");

        Order orderA = new Order().setPayState(OrderState.NOT_PAYED).setPrice(BigDecimal.valueOf(12))
                                  .setDueDate(LocalDateTime.of(1999, 2, 3, 12, 22))
                                  .setWorkState(OrderState.QUEUED).setCreatedDate(LocalDateTime.now());
        Order orderB = new Order().setPayState(OrderState.PAYED).setPrice(BigDecimal.valueOf(12))
                                  .setDueDate(LocalDateTime.of(1999, 2, 3, 12, 22))
                                  .setWorkState(OrderState.DELAYED).setCreatedDate(LocalDateTime.now());

        workerA.getOrders().add(orderA);
        workerB.getOrders().add(orderB);

        userRepo.save(workerA);
        userRepo.save(workerB);

1 Ответ

0 голосов
/ 24 марта 2020

У вас нет cascade = CascadeType.ALL на обоих концах отношения. В вашем случае это означает, что если вы попытаетесь удалить пользователя, он автоматически удалит его записи user_order.

Если вы удалите заказ (однако, как вы делаете), поскольку он не каскадный, он не имеет полномочий удалить из user_order, и в этой таблице у вас все еще есть записи, указывающие на ордер, который вы пытаетесь удалить.

Либо сначала вручную удалите все записи user_order, в которых этот ордер присутствует, и только затем удалите сам ордер или поместите cascade = CascadeType.ALL здесь @ManyToMany(mappedBy = "orders", cascade = CascadeType.ALL)

...