Mam następujący układ zajęć:Kolejność zapisywania kaskadowego GORM w zależności od nazw pól? Naprawdę?
class A {
static belongsTo = [c: C]
B b
}
class B {
static belongsTo = [c: C]
}
class C {
static hasMany = [bbs: B, aas: A]
}
Gdybym teraz tworzyć instancje tych klas ...
B b = new B()
A a = new A()
a.b = b
C c = new C()
c.addToBbs(b)
c.addToAas(a)
... i spróbuj zapisać c ...
c.save()
... Otrzymuję org.hibernate.TransientObjectException Message object references an unsaved transient instance - save the transient instance before flushing: B
.
To, co myślę, że GORM robi, to najpierw kaskada zapisu do c.aas
, a następnie potknie się o instancję a.b
, która nie jest jeszcze zapisana. Dlatego wyjątek.
Teraz trick: Gdybym przemianowany na własność C
aas
do xxs
, to działa:
class C {
static hasMany = [bbs: B, xxs: A]
}
b
zostaje zapisany, potem a
. GORM wydaje się kaskadować zapisy w porządku leksykograficznym pól (najpierw bbs
, następnie xxs
)!
Jak mogę kontrolować kolejność użycia GORM dla zapisu kaskadowego (z wyjątkiem zmiany nazwy pól, co wydaje mi się bardzo kruche)?
To może nie odpowiedzieć na dokładną pytanie, ale były zapisuje zawinięte w transakcji? Spodziewałbym się twojej pierwszej próby pracy tak długo, jak wszystko było transakcyjne. –
Tak. Podczas zapisywania była aktywna transakcja. –
Przepraszam, naciśnij przycisk edycji zbyt wcześnie. Czy to działa, jeśli używasz "c.addToAas (a)" (bez c.addToBbs (b))? Nie jestem pewien, czy zapisy spadną do trzeciego poziomu, ale warte strzału (chciałbym też wiedzieć, czy sugestia Gaurava o "kaskadzie: oszczędzanie" działa, ale nie spodziewałbym się, że to coś zmieni, biorąc pod uwagę domyślne mapowanie dla hasMany to "cascade: all".) –