9

这是给 Grails 用户的。我在 grails - user mailing list 上问过它,但我想既然我已经为此奋斗了几天,我应该尽可能广泛地撒网。

我在尝试在引用这两个对象的另一个对象(不同类型)中对相同类型的两个对象之间的关系进行建模时遇到了一些困难。

作为我正在尝试做的一个示例,假设您正在模拟家庭成员之间的关系。任何给定的关系“属于”两个不同的家庭成员。所以:

class Person {
   hasMany[relationships: Relationship]

   static mappedBy = [relationships:'p1', relationships:'p2']
}

class Relationship {

   Person p1
   Person p2
   String natureOfRelationship // for example, "cousins"

   static belongsTo = [p1: Person, p2: Person]
}

这里的意图是如果 p1 或 p2 被删除,则删除将级联到 hasMany 映射中的所有关系对象。相反,每次我尝试它时,我都会遇到外键违规。我尝试使用文档中介绍的“级联”属性:

http://grails.org/doc/1.0.x/guide/single.html#5.5.2.9%20Custom%20Cascade%20Behaviour

所以我想我会把它添加到 Person 类中:

static mapping = {
    relationships cascade:'delete'
}

我也没有运气。

我还查看了 Grails 生成的 devDB.script 文件,以了解它是如何在关系上设置外键的。如果我手动将“ON DELETE CASCADE”添加到两个外键约束,那么它工作正常,但显然对自动生成的数据库脚本进行手动编辑并不是最强大的解决方案。理想情况下,我希望能够使用 GORM 指定该行为。

那么我在这里最好的选择是什么?有没有办法强制级联删除多个外键/所有者?我是否需要通过对 Person 的 onDelete 操作手动执行此操作?我是否需要为此进入 Hibernate 配置,或者我可以在 Grails/GORM 中以某种方式做到这一点?

非常感谢您抽出宝贵的时间以及您可以提供的任何帮助。

4

2 回答 2

1

您可以向 Person 类添加一个beforeDelete挂钩并查询另一个父类。如果另一个父级不存在,您可以删除该关系。请注意,您遇到外键违规是因为您可能需要删除两个父级,因为该关系对它们都有一个 FK。

于 2009-09-28T18:13:29.893 回答
0

您还可以在 Person 中定义 2 个关系集合

传入关系和传出关系似乎可以用来区分(如果适用于您的域)。

您可以仅使用 getter 定义瞬态属性关系,它返回两个关系集合的联合(一个不可变的确保不修改它/这些更改很可能没有意义)

class Person {
   Relationship incomingRelations
   Relationship outgoingRelations
   static mappedBy = [incomingRelations:'p1', outgoingRelations:'p2']

   static transients = ['relations']

   Set getRelations() {
       //creates a new collection as union of the old ones
       return Collections.unmodifiableSet(this.incomingRelations + this.outgoingRelations)
   }
}
class Relationship {
    static belongsTo = [p1:Person, p2:Person]
}

如果不适合,我会尝试 Miguel-Ping 建议的均匀方法

于 2009-10-05T13:15:32.087 回答