从父进程中删除子进程需要获取父进程的所有子进程吗?

时间:2017-02-12 11:49:47

标签: java hibernate

我有两个这样的实体:

@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+子链接。查询所有孩子是非常缓慢和不可接受的。

如何解决此问题或以其他方式使用?

2 个答案:

答案 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);