28

I have a Department entity which relations are as follows:

  1. Many departments can be in one parent department:

    @ManyToOne
    @JoinColumn(name = "ik_parent_department_id")
    private Department parentDepartment;
    
  2. One parent department can have many departments:

    @OneToMany(mappedBy = "parentDepartment")
    private Set<Department> children = new HashSet<Department>(0);
    

And I want to implement the next: When I delete a department, then the ik_parent_department_id parameter of all children of this department is set to null. Any ideas how to do that?

pirho
  • 11,565
  • 12
  • 43
  • 70
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498
  • 1
    possible duplicate of [Have JPA/Hibernate to replicate the "ON DELETE SET NULL" functionality](http://stackoverflow.com/questions/9944137/have-jpa-hibernate-to-replicate-the-on-delete-set-null-functionality) – s.Daniel Jan 23 '15 at 09:29

3 Answers3

14

With JPA, in parent Entity you might have something like

@OneToMany(mappedBy="parent", cascade={CascadeType.PERSIST})
Collection<Child> children;

and in order to avoid possible repeating "set null code" & integrity violation exceptions on parent removal implement in parent Entity also

@PreRemove
private void preRemove() {
   children.forEach( child -> child.setParent(null));
}
pirho
  • 11,565
  • 12
  • 43
  • 70
13

You'll have to set the children's ik_parent_department_id to null explicitly.

Department parentDepartment = (Department) session.load(Department.class, id);
session.delete(parentDepartment);
for (Department child : parentDepartment.getChildren()){
    child.setParentDepartment(null);
} 
session.flush();

With cascading you would only manage to delete child Departments.

Xavi López
  • 27,550
  • 11
  • 97
  • 161
  • 2
    No there is not. It is possible to set up the fk in the db to do this in some databases but the support is limited. E.g. with sql server you run into problems with circle references so implementing the logic into the code looks like proposed. See also: http://stackoverflow.com/questions/9944137/have-jpa-hibernate-to-replicate-the-on-delete-set-null-functionality – s.Daniel Jan 23 '15 at 09:28
6

Just code it:

for (Department child : parent.getChildren()) {
    child.setParentDepartment(null);
}
session.delete(parent);
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255