@Entity
@Table(name="Student")
public class Student {
private String id;
private String firstName;
private String lastName;
private Set<Grade> grades = new HashSet<Grade>();
public void addGrade(Grade grade){
grades.add(grade);
}
//rest of Getters and setters omitted
public void removeGrade(Grade grade){
grades.remove(grade);
}
@OneToMany(cascade = CascadeType.ALL,fetch=FetchType.LAZY,orphanRemoval=true)
@JoinColumn(name="s_id")
public Set<Grade> getGrades() {
return grades;
}
等级:
@Entity
@Table(name="Grade")
public class Grade {
//all omitted
}
我有对象学生,我想删除ID为'xyz'的学生评分集中的一个现有成绩
我正在做以下事情:
String id = "xyz";
Session session = sessionFactory.getCurrentSession();
Student student = (Student)session.load(Student.class,id);
student.removeGrade(grade);
session.update(student);
一切都运行完美,但在SQL查询中,我看到了奇怪的更新:
Hibernate: select student0_.id as id0_0_, student0_.FirstName as FirstName0_0_, student0_.LASTNAME as LASTNAME0_0_ from Student student0_ where student0_.id=?
Hibernate: select grades0_.s_id as s4_0_1_, grades0_.id as id1_, grades0_.id as id1_0_, grades0_.FirstQuestion as FirstQue2_1_0_, grades0_.TotalGrade as TotalGrade1_0_ from Grade grades0_ where grades0_.s_id=?
Hibernate: update Grade set s_id=null where s_id=? and id=?
Hibernate: delete from Grade where id=?
为什么我有更新? update Grade set s_id=null where s_id=? and id=?
如何跳过它,以提高性能?
答案 0 :(得分:1)
这似乎是不必要的,因为你的级联类型是ALL,它就是你的情况。但是,有一些数据模型可能使Child能够独立于另一个实体的多对多关系而存在。换句话说,如果您不想删除从Student到Grade的关系,则更新有意义。在这种情况下,hibernate应该只取消外键值,但不能删除Grade行。
所以这就是发生的事情 - 当您通过从父集合中删除子节点来明确地断开关系时,hibernate知道更新子表以删除外键。当你的级联设置使用'ALL'设置(它实际上可能是orphanRemoval = true)时,hibernate知道删除实际子行时它不再有父行。我怀疑hibernate没有经过优化,因此它可以识别何时可以删除。
这可能是他们刚刚选择不实施的优化。
您可以阅读有关收藏效果here的信息。特别是第19.5节。