【发布时间】:2011-12-08 17:44:03
【问题描述】:
使用cascade = CascadeType.REMOVEhibernate 不会在表生成期间添加“ON DELETE CASCADE”。这是正确的行为吗?如果我在父对象上执行 em.remove() 没问题,但是当我尝试通过 HQL 执行批量删除时会出现错误。
PostgreSQL 9.1,休眠 4.0.0.CR7
【问题讨论】:
标签: hibernate
使用cascade = CascadeType.REMOVEhibernate 不会在表生成期间添加“ON DELETE CASCADE”。这是正确的行为吗?如果我在父对象上执行 em.remove() 没问题,但是当我尝试通过 HQL 执行批量删除时会出现错误。
PostgreSQL 9.1,休眠 4.0.0.CR7
【问题讨论】:
标签: hibernate
您正在寻找的是@OnDelete 注释,它会影响休眠模式生成(DDL 语句)。但是,当数据库中的外键定义中没有 ON DELETE CASCADE 子句时,此注释不会将删除级联到引用实体/行。
@OneToMany
@OnDelete(action=OnDeleteAction.CASCADE)
public Set<Stuff> getStuff() {
return stuff;
}
【讨论】:
cascade = CascadeType.REMOVE 时,其他 ORM 是否适用 ON DELETE CASCADE?
@OneToOne 映射工作得很好。使用休眠 4.2.1。
这是预期的行为。 cascade 注解告诉 Hibernate 级联删除,这是 Hibernate 而不是数据库的责任。
批量删除查询完全绕过会话和实体级联注释。当您选择使用它们时,您必须自己处理级联删除。
【讨论】:
我的理解是,您所指的“ON DELETE CASCADE”功能是数据库触发器。 Hibernate 不配置触发器。使用注解,Hibernate 将使用标准的 SELECT 和 DELETE 语句管理子对象的删除。如果您打开调试,您将看到这种情况发生。当您第一次开始使用休眠时,这看起来效率非常低,所以当您希望通过您所指的 HQL 使用批量删除时。
因此,表生成不会添加触发器等数据库特定功能。如果您希望能够删除子对象,请根据您的要求尝试这样的操作
@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true)
private List<Case> cases = new ArrayList<Case>();
当直接使用 HQL 时,它会绕过级联逻辑,因此您可能必须编写自己的“清理”代码,定期运行以清理或清理等。为了提高效率,我选择为此编写存储过程。
另一种方法是检索要删除的父对象的集合,并逐个遍历它们。如果您的集合很大,这效率不高,但至少会像您在注释中定义的那样级联。
【讨论】: