Hibernate不添加'on delete cascade'

时间:2011-12-08 17:44:03

标签: hibernate

使用cascade = CascadeType.REMOVE hibernate不会在表生成期间添加“ON DELETE CASCADE”。这是正确的行为吗?如果我在父对象上执行em.remove(),但是当我尝试通过HQL执行批量删除时出错,则没问题。

PostgreSQL 9.1,Hibernate 4.0.0.CR7

3 个答案:

答案 0 :(得分:7)

您正在寻找的是@OnDelete注释,它通过hibernate(DDL语句)影响模式生成。但是,如果数据库中的外键定义中没有ON DELETE CASCADE子句,则此批注不会在批量删除时级联删除引用实体/行。

@OneToMany
@OnDelete(action=OnDeleteAction.CASCADE)
public Set<Stuff> getStuff() {
  return stuff;
}

答案 1 :(得分:2)

这是预期的行为。级联注释告诉Hibernate级联删除,这是Hibernate的责任,而不是数据库,这样做。

批量删除查询完全绕过会话,实体级联注释。当你选择使用它们时,你必须处理级联删除你自己。

答案 2 :(得分:1)

我的理解是你所指的'ON DELETE CASCADE'功能是一个数据库触发器。 Hibernate不配置触发器。使用注释,Hibernate将使用标准的SELECT和DELETE语句管理子对象的删除。如果你打开调试,你会发现这种情况。当你第一次开始使用hibernate时,这看起来非常低效,所以当你想通过你所指的HQL使用批量删除时。

因此,表生成不会添加触发器等数据库特定功能。如果您希望能够删除子对象,请尝试根据您的要求进行此类操作

@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true)
private List<Case> cases = new ArrayList<Case>();

直接使用HQL时,它会绕过级联逻辑,因此您可能必须编写自己的“清理”代码,该代码会定期运行以清理orhapns等。为了提高效率,我选择为此目的编写存储过程。

另一种方法是检索要删除的父对象的集合,并逐个循环遍历它们。如果你的收藏很大,这个效率不高,但至少会按照你在公告中的规定进行级联。