Используйте JPA / Hibernate для репликации функции «ON DELETE SET NULL» - PullRequest
32 голосов
/ 30 марта 2012

Мне удалось использовать JPA / Hibernate для успешной репликации функциональности ON DELETE CASCADE (похоже на поведение по умолчанию), но сейчас я пытаюсь повторить функциональность ON DELETE SET NULL, и у меня возникают проблемы.

Это мои два класса:

@Entity
@Table(name = "teacher")
public class Teacher
{
    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false, length = 4)
    private int id;

    @OneToMany(mappedBy = "teacher")
    private List<Student> studentList;

    // ...
}

@Entity
@Table(name = "student")
public class Student
{
    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false, length = 4)
    private int id;

    @ManyToOne(optional = true)
    @JoinColumn(name = "teacher_id", nullable = true)
    private Teacher teacher;

    // ...
}

Когда я пытаюсь удалить учителя, появляется следующая ошибка:

org.springframework.dao.DataIntegrityViolationException: не удалось выполнить пакетное обновление JDBC; SQL [удалить из учителя, где teacher_id =?]; ограничение [ноль]
...
Вызвано: org.hibernate.exception.ConstraintViolationException: не удалось выполнить пакетное обновление JDBC
...
Вызвано: java.sql.BatchUpdateException: пакетная запись 0 удаляется из учителя, где teacher_id = '1' был прерван. Вызовите getNextException, чтобы увидеть причину.

Я что-то не так делаю? Это что-то достижимое?

Спасибо.

Ответы [ 3 ]

33 голосов
/ 05 апреля 2012

В настоящее время это невозможно с помощью jpa / hibernate.

При удалении установить ноль в спящем режиме в @ OneToMany

Решение JBs кажется чистым:

for (Department child : parent.getChildren()) {
    child.setParentDepartment(null);
}
session.delete(parent);

Вы также должны иметь возможность поместить его в PreRemove:

@PreRemove
private void preRemove() {
    for (Student s : studentList) {
        s.setTeacher(null);
    }
}
3 голосов
/ 08 июня 2015

Как насчет определения

@ForeignKey(name = "fk_student_teacher",
            foreignKeyDefinition = " /*FOREIGN KEY in sql that sets ON DELETE SET NULL*/")

?

1 голос
/ 19 февраля 2017

Я думаю, что лучшим решением является инструкция SQL пользователя для настройки действия удаления следующим образом:

CREATE TABLE table_name
(
  column1 datatype null/not null,
  column2 datatype null/not null,
  ...

  CONSTRAINT fk_column
     FOREIGN KEY (column1, column2, ... column_n)
     REFERENCES parent_table (column1, column2, ... column_n)
     ON DELETE SET NULL
);

когда пользователь удаляет строку другим каскадным удалением, когда вы используете ссылку таблицы на эту удаленную строку, вы не можете использовать решение гибернации и возвращать исключение SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...