объединить два доменных объекта и переназначить детей одному из них в Grails - PullRequest
0 голосов
/ 01 июня 2011

У меня есть две записи в доменном объекте, которые я хочу объединить. Давайте назовем родительский дом и детскую комнату. У меня есть ситуация, когда я хочу объединить два доменных домена, которые на самом деле одинаковы. У меня есть логика, чтобы сделать это слияние верхнего уровня.

Однако я хочу знать, есть ли способ, позволяющий Grails легко сказать: «Пройдите через доменные объекты и, где есть указатель fk на House, обновите этот fk до нового значения».

код будет примерно таким

houseInst1.magicMerge(houseInst2)

Это запустит слияние House, а также проверит каждый объект домена, имеющий указатель (fk) на House, и обновит место, где он изначально указывает на houseInst2, чтобы указывать на houseInst1.

Обновление: одна из ключевых особенностей заключается в том, что мне бы хотелось, чтобы это работало, если бы кто-то добавил еще один объект домена со ссылкой на главный объект. например. если кто-то добавил ипотечные кредиты позже, я не хочу обновлять всю мою логику слияния, он должен пойти и обнаружить, что ипотечные кредиты являются дочерними для Хауса, и обновить соответствующим образом.

Ответы [ 2 ]

2 голосов
/ 01 июня 2011

Объекты домена Grails предоставляют метод hibernate merge(), но это делает что-то совершенно другое: он сливает (возможно, отсоединенный) объект обратно в контекст постоянства.

Мне не известны какие-либо встроенные функции для объединения двух объектов, которые вы описываете. Я думаю, вам нужно вручную обновить внешние ключи, как в ответе Грегга. Более эффективный способ сделать обновление - через HQL, например:

Room.executeUpdate('update Room set house = :newHouse where house = :oldHouse',
    [newHouse: newHouse, oldHouse: oldHouse])

Редактировать: для автоматического обновления всех ассоциаций, вы можете опросить Артефакт:

def artefact = grailsApplication.getArtefact("Domain", "House")
artefact.associationMap.values().each { associationClass ->
    associationClass.executeUpdate("update ${associationClass.simpleName} set house = :newHouse where house = :oldHouse",
        [newHouse: newHouse, oldHouse: oldHouse])
}
1 голос
/ 01 июня 2011

Как насчет этого? Вы захотите сделать это до того, как избавитесь от старого дома.

Room.findAllByHouse(oldHouse).each { room ->
    room.house = newHouse
    room.save()
}

Я не пробовал этого, и я предполагаю довольно стандартные отношения OneToMany между House и Room.

...