it-swarm.com.de

Haben Sie JPA/Hibernate, um die Funktion "ON DELETE SET NULL" zu replizieren

Ich konnte JPA/Hibernate haben, um die ON DELETE CASCADE-Funktionalität erfolgreich zu replizieren (scheint das Standardverhalten zu sein), aber ich versuche jetzt, die ON DELETE SET NULL-Funktionalität zu replizieren, und ich habe Probleme.

Dies sind meine zwei Klassen:

@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;

    // ...
}

Wenn ich versuche, einen Lehrer zu löschen, wird der folgende Fehler angezeigt:

org.springframework.dao.DataIntegrityViolationException: JDBC-Stapelaktualisierung konnte nicht ausgeführt werden. SQL [Von Lehrer löschen, wobei Lehrer_ID =?]; Einschränkung [null]
...
Verursacht durch: org.hibernate.exception.ConstraintViolationException: JDBC-Stapelaktualisierung konnte nicht ausgeführt werden
...
Verursacht durch: Java.sql.BatchUpdateException: Batch-Eintrag 0 vom Lehrer löschen, wobei teacher_id = '1' abgebrochen wurde. Rufen Sie getNextException auf, um die Ursache zu sehen.

Mache ich etwas falsch? Ist es etwas Erreichbares?

Vielen Dank.

31
satoshi

Mit jpa/hibernate scheint es momentan nicht möglich zu sein.

Beim Löschen in @OneToMany auf Null setzen

Die Lösung von JBs scheint jedoch sauber zu sein:

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

Sie sollten es auch in einer PreRemove-Datei speichern können:

@PreRemove
private void preRemove() {
    for (Student s : studentList) {
        s.setTeacher(null);
    }
}
32
kevingallagher

Was ist mit dem Definieren

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

?

3
Michał Ziobro

Ich denke, die beste Lösung ist eine Benutzer-SQL-Anweisung zum Setzen der Löschaktion wie folgt:

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
);

wenn der Benutzer eine Zeile durch ein anderes kaskadierendes Löschen löscht, wenn Sie einen Tabellenverweis auf diese gelöschte Zeile verwenden, konnten Sie keine Hibernat-Lösung und keine SQL-Ausnahmebedingung zurückgeben.

1
M2E67