Grails-GORM约束

Grails-GORM约束,grails,constraints,gorm,Grails,Constraints,Gorm,鉴于以下两个领域: class Follows { User followee ... static belongsTo = [follower: User] } class User { String name String lastName ... static hasMany = [ follows: Follows ] static mappedBy = [ follows: 'follower' ] } 这将创建下表:

鉴于以下两个领域:

class Follows {
    User followee
    ...
    static belongsTo = [follower: User]
}

class User {
    String name
    String lastName
    ...
    static hasMany = [ follows: Follows ]
    static mappedBy = [ follows: 'follower' ]
}
这将创建下表:

+------+-------------+-------------+
|  id  | follower_id | followee_id |
+------+-------------+-------------+
| 1    | 1           | 3           |
| 2    | 3           | 2           |
| 3    | 2           | 1           |
+------+-------------+-------------+
有没有办法通过禁制来防止跟随者的重复?我试图阻止两个方向,比如,如果用户Id 1已经在用户Id 3之后,那么用户Id 3应该不能跟随用户Id 1

换句话说,这就是我试图阻止的:

+------+-------------+-------------+
|  id  | follower_id | followee_id |
+------+-------------+-------------+
| 1    | 1           | 3           |
| 2    | 3           | 1           |
+------+-------------+-------------+
我知道我可能能够在插入之前查询数据库,以检查用户1是否在跟踪3(或者相反),如果为true,则取消插入,但我试图避免每次跟踪操作都两次命中DB


干杯,谢谢你的回答

不,不存在处理此类情况的约束。您可以创建自己的约束,但它必须查询数据库,因此没有意义

但是,如果向
Follows
添加一个新属性,该属性包含一个适用于以下两个方向的唯一值,则可以使用唯一约束

class Follows {
    User followee
    ...
    Integer someUniqueProperty

    static belongsTo = [follower: User]

    static constraints = {
        someUniqueProperty unique: true
    }

    def beforeInsert() {
        someUniqueProperty = calculateUniqueProperty()
    }

    def beforeUpdate() {
        someUniqueProperty = calculateUniqueProperty()
    }

    private Integer calculateUniqueProperty() {
       [follower.id, followee.id].sort().hashCode()
    }
}
在上面的示例中,
someUniqueProperty
之后的所有实例中必须是唯一的。在插入/更新实例之前,通过将
follower
followee
放在一个列表中,始终以相同的顺序设置其值,然后获取哈希代码。这是基于以下事实:
[1,3].hashCode()==[3,1].sort().hashCode()


简而言之,添加一个独特的属性可以让数据库强制执行您需要的约束。

尽管像约束使用这样更优雅的解决方案会很好,但您的解决方案非常简单,非常出色。真棒的回答!干杯不客气。顺便说一句,我的解决方案确实使用了约束。看看这个例子中的约束闭包。是的,我指的是一个简单的约束,用来防止在两个方向上重复,而不是使用散列。顺便说一句,我测试了它,它工作得很好。