【问题标题】:Hibernate does not add 'on delete cascade'Hibernate 不添加“删除级联”
【发布时间】:2011-12-08 17:44:03
【问题描述】:

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

PostgreSQL 9.1,休眠 4.0.0.CR7

【问题讨论】:

    标签: hibernate


    【解决方案1】:

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

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

    【讨论】:

    • 休眠会让我发疯。 @OnDelete 适用于@OneToMany,但不适用于@OneToOne!此外,它不是便携式的。 cascade = CascadeType.REMOVE 时,其他 ORM 是否适用 ON DELETE CASCADE
    • @tscho 知道如何通过一对一映射实现这一点吗??
    • @Sikorski 我设法使用@OneToOne 映射工作得很好。使用休眠 4.2.1。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我的理解是,您所指的“ON DELETE CASCADE”功能是数据库触发器。 Hibernate 不配置触发器。使用注解,Hibernate 将使用标准的 SELECT 和 DELETE 语句管理子对象的删除。如果您打开调试,您将看到这种情况发生。当您第一次开始使用休眠时,这看起来效率非常低,所以当您希望通过您所指的 HQL 使用批量删除时。

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

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

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

      另一种方法是检索要删除的父对象的集合,并逐个遍历它们。如果您的集合很大,这效率不高,但至少会像您在注释中定义的那样级联。

      【讨论】:

        猜你喜欢
        • 2012-08-16
        • 1970-01-01
        • 2014-11-16
        • 2013-01-13
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        • 2013-10-11
        相关资源
        最近更新 更多