在父记录之前保存子记录时出现异常:
GrailsWrappedRuntimeException: ORA-02291:
integrity constraint (GRB.FKF8F6B734389E9766) violated -
parent key not found
代码:
class Child {
Parent parent
static constraints = {
parent nullable: true
}
}
class Parent {
static hasMany = [ children: Child ]
}
def child = new Child()
child.save() // first save of Child
def parent = new Parent()
parent.save()
//session.flush() // the sudden flush
child.parent = parent
child.save()
// here is 'constraint violation' when transaction is committed
正如异常消息中所说,Child
设置了父密钥Parent
,但不知何故,Hibernate当时没有将该密钥视为现有行。。。
上面是我的代码中发生的事件的简化重建。请注意,这些操作是在代码的不同位置执行的(设计为相互分离)。不幸的是,这样一个缩小的代码工作得很好,并没有重现问题。。。此外,我以前从未遇到过这样的问题——我曾经在父记录之前保存子记录,反之亦然,没有任何问题。
我可以通过两种方式修复代码:
- 评论
Child
的"第一次保存"(保存顺序很重要?!) - 或取消对会话刷新的注释
虽然我可以修复它,但我真的不想依赖于诸如保存顺序或突然的慌乱之类的事情。。。知道如何解决仍然有可靠代码的问题吗?
Grails 2.2.0、Hibernate 3.6、Oracle XE
您的异常可能是因为您在子表上没有可为null的parent
约束的情况下进行了测试。如果没有null,那么在现有条目和新条目中就会有一个0或其他东西,因为DB正在发挥一些神奇的作用。GORM不会删除现有的FK,也不会向现有列添加可为null的约束。请尝试手动删除约束或删除整个列。仔细检查parent_id
列上的可为null的约束。
关于你的问题,我建议你在父母身上添加孩子,而不是把孩子保存为孩子:
parent.addToChildren(child)
如果以前没有保存,这也会隐式保存子项。