GORM级联保存的顺序取决于字段名称?真的吗?
Posted
技术标签:
【中文标题】GORM级联保存的顺序取决于字段名称?真的吗?【英文标题】:Order of GORM cascaded saves depending on field names? Really? 【发布时间】:2015-04-27 19:19:57 【问题描述】:我的课程安排如下:
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
。因此例外。
现在诀窍:如果我将C
的aas
属性重命名为xxs
,它会起作用:
class C
static hasMany = [bbs: B, xxs: A]
b
首先被保存,然后是a
。 GORM 似乎按照字段的字典顺序级联保存(首先是bbs
,然后是xxs
)!
如何控制 GORM 用于保存级联的顺序(重命名字段除外,这对我来说似乎很脆弱)?
【问题讨论】:
这可能无法回答您的确切问题,但保存是否包含在事务中?只要一切都是事务性的,我希望您的第一次尝试能够奏效。 是的。保存时有一个活跃的交易。 抱歉,按编辑按钮太早了。如果您使用“c.addToAas(a)”(没有 c.addToBbs(b)),它是否有效?我不确定保存是否会级联到第三级但值得一试(我也很想知道 Gaurav 对“级联:保存”的建议是否有效,但我不希望它会有所作为,给定 hasMany 的默认映射是“cascade: all”。) 您好,正在尝试清理未答复的内容。你解决了吗?也许你可以回答你自己的问题。 我没有解决。可能没有办法控制它。 【参考方案1】:据我所知,GORM 没有提供一种方法来控制保存级联应用于属性的顺序。
我认为您应该能够使用以下方法之一解决此问题:
1] 在保存 A
之前显式保存 B
的实例(就像没有 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] 在类A
中为属性b
定义custom cascading behavior
class A
static belongsTo = [c: C]
B b
static mapping =
b cascade: 'save'
注意:这两种方法都没有经过测试
【讨论】:
【参考方案2】:在我的多对多中,我在尝试做 .addTo 之前保存了 C 类
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/
【讨论】:
这不适合我。没有 A 和 B 就无法存储 C。我知道 GORM Gotcha 文章(你说得对,它们真的很棒)。 是的,首先保存的顺序很重要,保存时会级联。与其将 aas 更改为 xxs 以使其按字母顺序保存,更好的解决方案是找出首先要保存的内容,然后按该顺序保存它们……这不是很用户友好吗??以上是关于GORM级联保存的顺序取决于字段名称?真的吗?的主要内容,如果未能解决你的问题,请参考以下文章