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

sat*_*shi 32 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;

    // ...
}
Run Code Online (Sandbox Code Playgroud)
@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;

    // ...
}
Run Code Online (Sandbox Code Playgroud)

当我尝试删除教师时,会出现以下错误:

org.springframework.dao.DataIntegrityViolationException:无法执行JDBC批量更新; SQL [从老师那里删除teacher_id =?]; constraint [null]
...
引起:org.hibernate.exception.ConstraintViolationException:无法执行JDBC批量更新
...
由以下引起:java.sql.BatchUpdateException:批量输入0从教师中删除,其中teacher_id ='1'已中止.调用getNextException以查看原因.

难道我做错了什么?这是可以实现的吗?

谢谢.

kev*_*her 34

目前用jpa/hibernate似乎不可能.

在@OneToMany中,在hibernate中删除set null

JBs解决方案似乎很干净:

for (Department child : parent.getChildren()) {
    child.setParentDepartment(null);
}
session.delete(parent);
Run Code Online (Sandbox Code Playgroud)

你也应该能够把它放在PreRemove中:

@PreRemove
private void preRemove() {
    for (Student s : studentList) {
        s.setTeacher(null);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `@ PreRemove`解决方案不可移植.请参阅JPA规范第3.5节.*通常,可移植应用程序的生命周期方法不应修改同一持久化上下文中的关系.* (7认同)

Mic*_*bro 5

怎么定义

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

?

  • 这仅用于在模式生成生效时指定关联数据库中的外键约束。 (3认同)