Grails 中没有双向关系的级联删除
我正在使用 Grails 1.3.7,并且具有以下域类:
package com.fxpal.test
class UserGroup {
String name
static constraints = {
name(blank: false)
}
}
class Invitation {
UserGroup group
String user
static belongsTo = [group: UserGroup]
static constraints = {
group(nullable: false)
}
}
我希望能够在删除 UserGroup 实例时删除引用该 UserGroup 实例的所有 Invitation 实例,而不具有引用 UserGroup 中的 Invitation 的显式关系。换句话说,我希望从 UserGroup 到 Invitation 进行级联删除,而不修改 Group。
由于表示邀请 -> 的约束,我对此的测试失败了。用户组关系:
void testCascadingDelete() {
UserGroup group1 = new UserGroup(name: 'group1').save(flush: true, failOnError: true)
UserGroup group2 = new UserGroup(name: 'group2').save(flush: true, failOnError: true)
Invitation invitation = new Invitation(user:'user1', group: group1).save(flush: true, failOnError: true)
assertEquals("Wrong number of groups.", 2, UserGroup.count())
assertEquals("Wrong number of invitations.", 1, Invitation.count())
group1.delete(flush: true, failOnError: true)
assertEquals("Wrong number of groups.", 1, UserGroup.count())
assertEquals("Wrong number of invitations.", 0, Invitation.count())
}
当我运行测试时,它失败如下:
could not delete: [com.fxpal.test.UserGroup#1]; SQL [delete from user_group where id=? and version=?]; constraint [FK473F7799A8642225]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
org.springframework.dao.DataIntegrityViolationException: could not delete: [com.fxpal.test.UserGroup#1]; SQL [delete from user_group where id=? and version=?]; constraint [FK473F7799A8642225]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
at com.fxpal.test.InvitationIntegrationTests.testCascadingDelete(InvitationIntegrationTests.groovy:23)
Caused by: org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
at com.fxpal.test.InvitationIntegrationTests.testCascadingDelete(InvitationIntegrationTests.groovy:23)
...
它看起来像规范的鼻脸示例,但级联删除似乎不起作用。我真的不想在 UserGroup 中表示 Invitation,特别是因为最终 Invitation 将引用其他几个域类,删除其中任何一个都会导致相应的 Invitation 也被删除。
我缺少什么?
基因
I am using Grails 1.3.7, and have the following domain classes:
package com.fxpal.test
class UserGroup {
String name
static constraints = {
name(blank: false)
}
}
class Invitation {
UserGroup group
String user
static belongsTo = [group: UserGroup]
static constraints = {
group(nullable: false)
}
}
I would like to be able to delete all Invitation instances that refer to a UserGroup instance when that UserGroup instance is deleted, without having an explicit relationship that refers to Invitation in UserGroup. In other words, I would like to have a cascading delete from UserGroup to Invitation, without modifying Group.
My test for this fails due to a constraint that represents the Invitation -> UserGroup relationship:
void testCascadingDelete() {
UserGroup group1 = new UserGroup(name: 'group1').save(flush: true, failOnError: true)
UserGroup group2 = new UserGroup(name: 'group2').save(flush: true, failOnError: true)
Invitation invitation = new Invitation(user:'user1', group: group1).save(flush: true, failOnError: true)
assertEquals("Wrong number of groups.", 2, UserGroup.count())
assertEquals("Wrong number of invitations.", 1, Invitation.count())
group1.delete(flush: true, failOnError: true)
assertEquals("Wrong number of groups.", 1, UserGroup.count())
assertEquals("Wrong number of invitations.", 0, Invitation.count())
}
When I run the test, it fails like this:
could not delete: [com.fxpal.test.UserGroup#1]; SQL [delete from user_group where id=? and version=?]; constraint [FK473F7799A8642225]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
org.springframework.dao.DataIntegrityViolationException: could not delete: [com.fxpal.test.UserGroup#1]; SQL [delete from user_group where id=? and version=?]; constraint [FK473F7799A8642225]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
at com.fxpal.test.InvitationIntegrationTests.testCascadingDelete(InvitationIntegrationTests.groovy:23)
Caused by: org.hibernate.exception.ConstraintViolationException: could not delete: [com.fxpal.test.UserGroup#1]
at com.fxpal.test.InvitationIntegrationTests.testCascadingDelete(InvitationIntegrationTests.groovy:23)
...
It seems like the canonical nose-face example, but the cascading delete doesn't seem to work. I really don't want to have to represent the Invitation in the UserGroup, in particular because in the end, the Invitation will reference several other domain classes, the deletion of any of which should cause the corresponding Invitation to get deleted as well.
What am I missing?
Gene
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定在没有双向关系的情况下是否可能,但您可以轻松地在事务服务方法中自己完成(以确保删除全部发生或没有发生):
然后您的测试变成了
一些不相关的小注释 -默认情况下,属性不为 null,因此您可以删除
group(nullable: false)
约束。并且 Map 形式的belongsTo
就像您定义了该名称的变量一样,因此您可以在Invitation
中省略UserGroup group
。更新:
另一个侵入性较小的选项是在
UserGroup
中使用 before-delete 事件:I'm not sure if it's possible without the bidirectional relationship, but you can easily do it yourself in a transactional service method (to make sure the deletes all happen or none happen):
and then your test becomes
A couple of minor unrelated notes - properties are not-null by default, so you can remove the
group(nullable: false)
constraint. And abelongsTo
in Map form like you have defines a variable of that name, so you can omitUserGroup group
inInvitation
.UPDATE:
Another less intrusive option is to use the before-delete event in
UserGroup
: