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。因此例外。

现在诀窍:如果我将Caas 属性重命名为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级联保存的顺序取决于字段名称?真的吗?的主要内容,如果未能解决你的问题,请参考以下文章

Grails/GORM 中的错误:已删除的对象将被级联重新保存

gorm软删除和硬删除

基于字段位置而非名称的 BigQuery 联合架构

外键关联的修改 级联 修改表行记录的操作

MongoDB添加字段取决于名称?

如何对 GORM 子文档字段进行不同的查询?