OneToMany 只删除关系的一部分

OneToMany deleting only one part of the relationship

所以,我有这些 classes:

@Entity
@Table(name="tbStudent")
public class Student {

    @OneToMany(mappedBy="student")
    private List<Report> reports;
}

@Entity
@Table(name="tbReport")
public class Report {

    @ManyToOne
    @JoinColumn(name="student_fk", updatable=true, nullable=true)
    private Student student;
}

我希望能够删除一名学生但保留报告。

那么,有没有办法将报告中的学生 FK 更新为空,以便我可以毫无问题地删除学生?

我在 HQL 中创建了一个函数,每次我尝试删除学生时都会将 FK 更新为空,但它似乎不起作用。

这里是:

public void deleteStudentReport(Student student){   
        String id = student.getId();
        EntityManager em = emf.createEntityManager();
        Query q = em.createQuery("update Report r set r.student.id = null where r.student.id = :id");
        q.setParameter("id", id);       
}

编辑:

我在尝试删除学生时调用查询:

@ManagedBean(name = "studentMB")
@ViewScoped
public class StudentMB {

    public void delete(){
        studentDao.deleteStudentReport(student);
        studentDao.delete(student);
   }

}

解决方案:

感谢 Naros 的回复,我最终在 Student 上设置了这个方法 class:

@PreRemove
public void preRemove(){
    for(Report r : reports){
        d.setStudent(null);
    }
}

您基本上只需要在 repository/dao class 或您的服务层的一部分上使用一个业务功能来获取报告实例并清除学生。

public void clearReportStudent(Report report) {
  if(report != null) {
    Student student = report.getStudent();
    if(student != null) {
      student.getReports().remove(report);      
      report.setStudent(null);
    }
  }
}

我通常更喜欢将这些类型的辅助方法放在我的域模型本身上,并根据需要从我的 service/business 逻辑中调用操作。

public class Report {
  public void unlinkFromStudent() {
    if(this.student != null) {
      this.student.getReports().remove(this);
      this.student = null;
    }
  }
}

希望对您有所帮助。