Подтвердить что ты не робот

Порядок каскадирования GORM сохраняется в зависимости от имен полей? В самом деле?

У меня есть следующее расположение классов:

class A {
    static belongsTo = [c: C]
    B b
}

class B {
    static belongsTo = [c: C]
}


class C {
    static hasMany = [bbs: B, aas: A]
}

Если я теперь создаю экземпляры этих классов...

B b = new B()
A a = new A()
a.b = b

C c = new C()
c.addToBbs(b)
c.addToAas(a)

... и попытайтесь сохранить c...

c.save()

... Я получаю org.hibernate.TransientObjectException Message object references an unsaved transient instance - save the transient instance before flushing: B.

Я думаю, что GORM делает сначала каскад сохранения в c.aas, а затем он натыкается на экземпляр a.b, который еще не сохранен. Поэтому исключение.

Теперь трюк: если я переименовал свойство aas в C в xxs, он будет работать:

class C {
    static hasMany = [bbs: B, xxs: A]
}

b сначала сохраняется, затем a. Кажется, что GORM каскадирует сохранение в лексикографическом порядке полей (сначала bbs, затем xxs)!

Как я могу контролировать последовательность использования GORM для каскадного сохранения (кроме переименования полей, которые мне кажутся очень хрупкими)?

4b9b3361

Ответ 1

Насколько я знаю, GORM не предоставляет способ контролировать последовательность, в которой сохраняются каскады для свойств.

Я думаю, вы должны решить это, используя один из следующих способов:

1] Явно сохраняю экземпляр B перед сохранением A (как всегда, для одной ассоциации без belongsTo)

B b = new B().save()  
A a = new A(b: b)  // b should already be persisted as A doesn't `belongsTo` B
C c = new C()
c.addToBbs(b)
c.addToAas(a)
c.save()

2] Определите настраиваемое каскадное поведение для свойства B в классе A

class A {
    static belongsTo = [c: C]
    B b

    static mapping = {
        b cascade: 'save'
    }
}

Примечание: ни один из них не был протестирован

Ответ 2

В моем много-для-многих я сохраняю класс C, прежде чем пытаюсь сделать .addTo

B b = new B()
A a = new A()
a.b = b

C c = new C()
c.save()
c.addToBbs(b)
c.addToAas(a)

В некоторых случаях мне приходилось определять настраиваемое каскадное поведение.

Эти статьи помогают понять такие проблемы.

https://spring.io/blog/2010/06/23/gorm-gotchas-part-1/

https://spring.io/blog/2010/07/02/gorm-gotchas-part-2/

https://spring.io/blog/2010/07/28/gorm-gotchas-part-3/