Grails在同一个域类中多对多

时间:2013-08-15 13:28:34

标签: grails grails-2.3

我想建立一个既可以有孩子也可以有父母的'实体'课程:

class Entity {
    static hasMany [childs: Entity, parents: Entity]
}

但我不知道如何映射我的数据(我应该使用mappedBy吗?)

我的测试:

@Test
void testEntityCanHaveAChild() {
    Entityparent = new Entity()
    Entitychild = new Entity()

    parent.addToChilds(child)

    assert parent.childs
    assert parent.childs.size() == 1
    assert parent.childs.contains(child)

    assert child.parents
    assert child.parents.size() == 1
    assert child.parents.contains(parent)
}

所以来自父母我希望能够让所有孩子和孩子我想得到所有父母

3 个答案:

答案 0 :(得分:1)

你不能那样做。

在一对多关联中,外键被放入"一个"一部分。

现在从你的例子中我明白,如果x是人y的孩子,那并不意味着y是人x的父母?人x可以有父母:人z和人t?

我将首先讨论当人x只能有一个父,如果x是y的子,那么y是x的父。

对于这种情况,我会添加一个新列,parent_id,默认值为null,并且只说hasMany [children:Person]和belongsTo [parent:Person] 这解决了一个孩子只能拥有一个父母的情况。

对于另一种情况,如果一个孩子可以有多个父母并且没有必要成为某个孩子的孩子,那么该孩子的父母就有两个选择: 1. db列中的id列表(我在关系数据库中不喜欢这个,但在NoSQL中是可以接受的) 2.连接台(2)。这可以是一个连接表多态,2个连接表或一个连接表有3列,一个将始终为null。 然后你需要将belongsTo添加到拥有的部分。并手动设置连接表的映射。类似的东西:

   static mapping = {
   hasMany joinTable: [name: 'parent_child_connection',
                       key: 'person_id',
                       column: 'parent_id']
}

答案 1 :(得分:1)

编辑:添加了addToChilds

我要做的是介绍另一个域名,例如父子

class ParentChild {
    Person parent
    Person child 
}

然后修改人

class Person {
def parents() {
    ParentChild.executeQuery("select pc.parent from ParentChild pc where pc.child = :child", [child:this])
}

def children() {
    ParentChild.executeQuery("select pc.child from ParentChild pc where pc.parent = :parent", [parent:this])
}
def addToChilds(Person child){
    New ParentChild(parent:this, child:child).save()
}
}

抱歉,我只熟悉HQL。不知道如何以更干净的方式做到这一点

答案 2 :(得分:0)

我发现这样做的唯一方法是在“两个表”之间添加一个多对多表,并像这样模拟“自动关系”:

class EntityBound {
    Entity parent
    Entity child 
}

class Entity {
    static hasMany [bounds: EntityBound]


    def childs() {
        EntityBound.findAllByParent(this).collect{ it.child }
    }

    def parents() {
        EntityBound.findAllByChild(this).collect{ it.parent }
    }

    Entity addChild(Entity entity){
        addToBounds(new EntityBound(parent:this, child:child))
        return this
    }
}