【问题标题】:Grails (GORM) Many-To-One Cascade Delete BehaviourGrails (GORM) 多对一级联删除行为
【发布时间】:2012-05-01 02:50:19
【问题描述】:

我一直在努力在一个相对简单的 Grails 项目中生成正确的配置以生成级联删除行为。

假设我有以下简单的域类:

class Author {
    String name
    static constraints = {
    }
}

class Book {
    String title
    Author author
    static constraints = {
    }
}

如果我创建了一个作者,然后创建了一本由该作者撰写的书,那么如果不先手动删除该书,我就无法删除该作者。我收到“违反完整性约束”。这并不奇怪,因为 MySQL(我的底层数据库)是由 Grails 创建的,在“book”表的“author”列上具有“外键约束”作为“Restrict”(并且这种行为与 Grails 的预期一致我理解的文档)。

现在,如果我要手动将 book 表的“作者”列上的基础数据库约束从“限制”更改为“级联”,我会得到我想要的行为。也就是说,如果您删除作者,他们的所有书籍也会被删除。

所以,我想做的是更改我的 Grails“Book”类,以在作者列上创建带有“on delete cascade”的“book”表。我一直在阅读大量关于使用“belongsTo”和显式“映射”做这类事情和 GORM 默认值的信息。

根据“belongsTo”的文档,一种方法似乎是将 Book 类中的行从:

Author author

static belongsTo = [author:  Author]

从而明确表明作者是关系的“拥有方”。该文档似乎表明这应该产生我所追求的级联删除行为。但是,除非我在 Author 类中添加明确的“hasMany = [books:Book]”,否则它不起作用。我不想这样做。 (这个愿望在我的实际业务领域中更有意义,但即使只是作为理解练习,我还不明白为什么我必须让 Author 领域类明确了解书籍)。

我想要一个 grails 设置来更改 Book 类以在数据库中生成“级联删除”设置,而无需更改 Author 类。我尝试使用如下显式映射:

static mapping = {
        author cascade: 'all'
}

以及它与其他显式映射或“belongsTo”选项的组合。这不起作用。

注意到对底层 SQL 数据库中“约束”的简单更改提供了我想要的行为,有没有办法通过 Grails 来实现?如果不是,我是否误解了一些基本的东西,还是我试图做一些愚蠢的事情?

【问题讨论】:

  • 你使用的是什么版本的 Grails?

标签: grails grails-orm belongs-to cascading-deletes


【解决方案1】:

我认为您在 Author 中缺少 Book 类型的必填字段。

这是示例代码,根据文档(经过测试和工作)

class Author {

    String name
    Book book //you are probably missing this field

    static constraints = {
    }
}

class Book {

    String name

    static belongsTo = [author: Author]

    static constraints = {
    }
}

测试用例:

@TestFor(Author)
@Mock([Book])
class AuthorTests {

    @Test
    void testAuthorBookCascades() {

        Author a = new Author(name: "Douglas Adams")
        Book b = new Book(name: "So Long, and Thanks for all the Fish")
        a.book = b
        a.save()

        assert Author.count() == 1
        assert Book.count() == 1

        a.delete()

        assert Author.count() == 0
        assert Book.count() == 0
    }
}

如您所见,您需要 Author 中的 Book 参数。不需要 hasMany 或 hasOne 子句。

【讨论】:

  • 感谢 Segar - 但我希望找到一种不涉及修改 Author 类/表的方法 - 只是以某种方式修改 book 表上的级联行为。但是,您说得对,这很有效(感谢您为概述它所做的努力)。我开始认为,也许您所说的是“正确”的做法,而我所要求的只是不是在开箱即用的 GORM 中设计的。
  • @Glennn 是的,您的要求没有定义,因为它不应该定义。这将意味着休眠将创建您未指定的约束,并且不是每个人都希望对所有内容进行级联删除。
  • @Glennn - 如果有外部约束,最好的方法是编写您自己的删除函数,以执行您想要的类似级联的行为。就 GORM 而言,GalmWing 所说的是正确的。
  • 谢谢大家。我确实编写了自己的删除函数。只是想可能有一种更好的方法来配置 GORM 来做到这一点,而我却错过了。 @GalmWing - 同意。我不希望 GORM 默认执行此操作 - 只是想知道是否有办法让我配置此行为。对概述的选项感到满意。
猜你喜欢
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多