我有一个简单的hasMany关联-一个UserGroup hasMany Users,而该UserGroup由一个User拥有:
class UserGroup {
String name
User owner
Set members = []
static hasMany = [members: User]
...
}
到目前为止很好。我希望名称对于每个所有者都是唯一的,因此最初对名称施加了限制:
name unique: 'owner'
但是,这也阻止了相同名称的更新。因此,我将约束移至beforeInsert并明确执行了逻辑:
def beforeInsert() {
boolean existing = false
UserGroup.withNewSession {
existing = UserGroup.where {
owner == this.owner && name == this.name
}.count() > 0
}
if (existing) {
this.errors.rejectValue(...)
}
return !this.hasErrors()
}
当使用成员保存一个新的UserGroup对象时,并且在beforeInsert通过之前,我看到了以下休眠操作:a)插入UserGroup,然后b)插入成员。
当使用成员保存新的UserGroup对象时,并且由于名称重复而beforeInsert失败,我只能看到休眠操作来插入成员。这当然会失败,因为没有父记录。
我是在做错什么,还是beforeInsert仅杀死了save()操作的一部分而不是整个事情,这是真的吗?怎么办?
最佳答案
beforeInsert上的代码应该在自定义验证器上,但是它正在检查唯一名称,因此正确的约束应该只是名称唯一:true(不确定唯一名称:'owner'的名称,因为它无效,所以值应该与规范boot一样https://docs.grails.org/latest/guide/validation.html)
而且,如果您希望组中的用户以级联方式保存,则可以在docs https://docs.grails.org/latest/ref/Database%20Mapping/cascade.html上指定的映射字段中指定
如果自定义验证器失败,或者仅唯一验证器失败,则不应执行级联保存/更新。