Нарушение ссылочной целостности: при удалении Entity в Hibernate (H2 в памяти СУБД) - PullRequest
0 голосов
/ 25 октября 2019

Я создаю свое первое приложение Spring Boot. Я использую Hibernate и СУБД в памяти H2.

Я пытаюсь создать REST API, представляющий несколько магазинов приложений. У меня есть объект с именем App, а другой - с именем Store. Магазин может содержать много приложений, и каждое приложение может содержаться в нескольких магазинах. Приложения, однако, не знают, в каких магазинах они содержатся. Я хочу иметь возможность удалять приложения и магазины независимо друг от друга. Тот факт, что магазин был удален, не означает, что приложения в нем также должны быть удалены, и наоборот. Приложения могут существовать, не находясь в магазине, и магазины без приложений тоже хороши.

Вот код для моих сущностей, LpApp - это реализация для приложения, а LpTemplate - это реализация для Магазина:

@Entity
public class LpApp {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false, updatable = false)
    private Long id;

    @NotBlank(message = "An app needs a non-empty name")
    @Column(nullable = false, updatable = false, unique = true)
    private String appName;

    // ... constructors, getters, setters, no further annotations
}

@Entity
public class LpTemplate {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false, updatable = false)
    private Long id;

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name = "template_apps",
        inverseJoinColumns = { @JoinColumn(name = "app_id") },
        joinColumns = { @JoinColumn(name = "template_id") })
    private Set<LpApp> apps = new HashSet<>();

    // ... constructors, getters, setters, no further annotations

}

Это работает, пока я не попытаюсь удалить приложение или магазин из моей СУБД. На этом этапе я получаю org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException.

Исключением, которое я получаю, является следующее (я сократил стек вызовов для краткости):

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["APP_ID: PUBLIC.TEMPLATE_APPS FOREIGN KEY(APP_ID) REFERENCES PUBLIC.LP_APP(ID) (3)"; SQL statement:
delete from lp_app where id=? [23503-199]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "APP_ID: PUBLIC.TEMPLATE_APPS FOREIGN KEY(APP_ID) REFERENCES PUBLIC.LP_APP(ID) (3)"; SQL statement:
delete from lp_app where id=? [23503-199]

Я, очевидно, делаючто-то не так, но я не знаю, где искать. Наверное, я не правильно использую аннотацию @ManyToMany или, возможно, это неправильная аннотация для моего варианта использования.

Большое спасибо.

1 Ответ

0 голосов
/ 25 октября 2019

Вам необходимо добавить атрибут каскада, чтобы указать hibernate не удалять объект при операции удаления. Существуют разные варианты каскада. Обратитесь к этой ссылке, чтобы понять различные варианты.

...