我有两个这样的实体:
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
@LazyCollection(LazyCollectionOption.EXTRA)
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childs = new ArrayList<>();
...Getter & Setter
}
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false)
private Parent parent;
...Getter & Setter
}
从父项中删除子项时,hibernate将查询该父项的所有子项:
parent.getChilds().remove(child);
我有父亲的100000+子链接。查询所有孩子是非常缓慢和不可接受的。
如何解决此问题或以其他方式使用?
答案 0 :(得分:0)
Hibernate必须获取所有子节点才能准备正确的SQL - 需要知道要删除的子元素的ID。 所以没有办法使用ORM以你想要的方式使用它,但是如果你问自己一个问题,你将如何在普通的SQL中做到这一点显而易见的解决方案
DELETE c FROM child c WHERE c.parent_id=parentId
Hibernate能够生成这样的查询,但它是通过HPQL完成的。因此,如果您已经明确了父级和子级之间的双向关系,并且child
具有parent
属性,那么您可以使用HPQL执行以下操作:
Query q=session.createQuery(`DELETE c FROM chilc WHERE c.parent=:parent`);
q.setObject("parent",parent);
q.execute(); // q.executeUpdate?
这样你就可以删除父节点的所有子节点而无需获取它们。
声明:
鉴于查询可能不是100%准确,因为我不再记得Hibernate的Session API
,但是给出了对解决方案的整体看法并且100%有效。只是向Hiberrnate的文档提供详细信息。
答案 1 :(得分:-1)
使用会话的delete
方法,而不使用Parent并级联更新:
sesionFactory.getCurrentSession().delete(child);
<强>更新强>
最好在删除之前执行合并,以确保其管理:
sesionFactory.getCurrentSession().merge(child);