2013-08-15 1 views
1

Я хочу построить класс «Entity», который может как иметь Чайлдс и родителей:Grails многие-ко-многим в том же домене класса

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) 
} 

Так от родитель Я хочу быть в состоянии получает все Чайлдс и от ребенка Я хочу получить всех родителей

ответ

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 
    } 
} 
1

Вы не можете сделать это так.

В ассоциации от одного до другого внешний ключ помещается в «одну» часть.

Теперь из вашего примера я понимаю, что если человек x является дочерним лицом человека y, это не означает, что человек y является родителем для человека x? человек x может иметь родителей: человек z и человек t?

Вначале обсудим случай, когда человек x может иметь только один родительский элемент и если x является дочерним по y, то y является родительским по отношению к x.

Для этого случая я бы добавил новый столбец parent_id со значением по умолчанию null и сказал только, что hasMany [children: Person] и принадлежит [parent: Person] Это разрешает случай, когда один ребенок может иметь только один родитель.

Для другого случая, когда у одного ребенка может быть несколько родителей и нет необходимости быть ребенком, чтобы кто-то сделал родителем для этого ребенка, есть два варианта: 1. списки идентификаторов в столбце db (я не как это в реляционной БД, но приемлемо в NoSQL) 2. соединительная таблица (2). Это может быть одна связующая таблица полиморфная, 2 соединительные таблицы или одна соединительная таблица с 3 столбцами, а одна всегда будет равна нулю. Затем вам нужно добавить принадлежность к принадлежащей части. И установите сопоставление для таблицы соединений вручную. что-то вроде:

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

Мне действительно нужно отношение «многие ко многим» как с ребенком, так и с родителем. – Thermech

1

Edit: Добавлена ​​addToChilds

Что бы я сделать, это ввести другой домен, например ParentChild

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. Не знаю, как это сделать более чистым способом.

+0

много для многих всегда есть средний стол. поэтому я предлагаю иметь контроль, написав среднюю таблицу как домен также – JavaDev