Grails - несколько принадлежностей одного класса с каскадным удалением

Это здесь для пользователей Grails. Я спросил об этом в списке рассылки grails - пользователей, но решил, что, поскольку я боролся с этим несколько дней, мне следует забросить как можно более широкую сеть.

Мне трудно смоделировать отношения между двумя объектами одного типа в другом объекте (другого типа), ссылаясь на эти два объекта.

В качестве примера того, что я пытаюсь сделать, предположим, что вы моделируете отношения между членами семьи. Любые отношения "принадлежат" двум разным членам семьи. Так:

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, то удаление будет происходить каскадно для всех объектов Relationship на карте hasMany. Вместо этого каждый раз, когда я пытаюсь это сделать, я получаю нарушение внешнего ключа. Я пробовал использовать атрибут «каскад», как описано в документации:

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

Итак, я решил добавить это в класс Person:

static mapping = {
    relationships cascade:'delete'
}

Мне и с этим не повезло.

Я также просмотрел файл devDB.script, который генерирует Grails, чтобы увидеть, как он настраивает внешние ключи в Relationship. Если я вручную добавлю «ON DELETE CASCADE» к обоим ограничениям внешнего ключа, тогда он будет работать нормально, но, очевидно, ручное редактирование автоматически сгенерированного сценария базы данных - не самое надежное решение. В идеале я хотел бы иметь возможность указать это поведение с помощью GORM.

Итак, что мне здесь лучше всего? Есть ли способ принудительного каскадного удаления нескольких внешних ключей / владельцев? Нужно ли мне делать это вручную с помощью действия onDelete для Person? Нужно ли мне для этого залезать в конфиги Hibernate или можно как-нибудь сделать это в Grails / GORM?

Большое спасибо за ваше время и за любую помощь, которую вы можете предложить.


person Community    schedule 03.09.2009    source источник
comment
Дэйв, как ты решил эту проблему? я думаю, что даже код: static mappedBy = [Relations: 'p1', Relations: 'p2'] проблематичен   -  person Hans Westerbeek    schedule 09.12.2010


Ответы (2)


Вы можете добавить перехватчик beforeDelete к классу Person и запросить другого родителя. Если другой родитель не существует, вы можете удалить связь. Обратите внимание, что вы сталкиваетесь с нарушениями внешнего ключа, потому что вам, вероятно, нужно удалить обоих родителей, поскольку у отношения есть FK для них обоих.

person Miguel Ping    schedule 28.09.2009

Вы также можете определить 2 коллекции Relationshipcollections лично

ВходящиеRelations и outgoingRelations кажутся удобными словами, чтобы различать их (если это применимо к вашему домену).

Вы можете определить временные отношения свойств только с помощью получателя, который возвращает объединение обеих коллекций отношений (неизменяемый, чтобы не изменять его / эти изменения, скорее всего, не имеют смысла)

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

если не подходит, я бы попробовал равномерный подход, предложенный Мигелем-Пингом

person squiddle    schedule 05.10.2009