我有一个简单的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上指定的映射字段中指定

如果自定义验证器失败,或者仅唯一验证器失败,则不应执行级联保存/更新。

10-07 12:27