让JPA / Hibernate复制“ON DELETE SET NULL”功能

时间:2012-03-30 13:41:03

标签: java hibernate jpa

我已经能够让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 =?];约束[null]
  ...
  引起:org.hibernate.exception.ConstraintViolationException:无法执行JDBC批量更新
  ...
  引起:java.sql.BatchUpdateException:批量输入0从教师中删除,其中teacher_id ='1'被中止。调用getNextException以查看原因。

我做错了吗?这是可以实现的吗?

谢谢。

3 个答案:

答案 0 :(得分:33)

目前似乎不可能使用jpa / hibernate。

On delete set null in hibernate in @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);
    }
}

答案 1 :(得分:3)

如何定义

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

答案 2 :(得分:1)

我认为最好的解决方案是用于设置删除操作的用户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
);

当用户通过其他级联删除删除行时,您使用对此已删除行的表引用,则无法使用hibernate解决方案并返回SQL异常。