验证域类的实例是唯一的

时间:2013-08-17 04:45:26

标签: grails

我有一个带有一堆域类的Grails应用程序,其中一些有很多字段,其中一些与所讨论的域类有hasMany的关系。对于这个特定的应用程序,我只有一个“约束”,即每个域类的每个实例都必须是唯一的。我不关心任意字段是否在同一域类的多个实例中具有相同的值,只要每个实例通过该域类中的某个其他字段的值使其唯一。所以基本上我希望验证发生在域类实例级别而不是域类字段级别。现在我通过使用非常常规的@EqualsAndHashCode注释来生成我的equalshashCode方法,然后在自定义验证器中调用某个任意字段的equals。域类。

两个问题:

  1. 是否有更有效的方法来验证域类是否唯一?
  2. 如果没有,那么有没有办法可以在域类实例上调用自定义验证器代码而不是通过域类实例的某个字段?
  3. @groovy.transform.EqualsAndHashCode
    class MyDomainClass {
        String some
        int arbitrary
        boolean field
        static constraints = {
            // The field I chose to validate on is irrelivant, I just need to run the validation code **somewhere**
            arbitrary validator: { val, obj ->
                return !MyDomainClass.getAll().contains(obj)
             }
        }
    }
    

    我还应该补充一点,我正在寻找一种通用(希望有效)的方法来做到这一点。我意识到调用getAll()是非常低效的,而是调用find的某个变体或对每个域类的确切字段执行HQL查询会更有效...它只需要更长的时间写!

    实施例

        assert MyDomainClass.getAll().isEmpty() // true
    
        def myDomainClass1 = new MyDomainClass( some: "foo", arbitrary: 1, field: true)
        assert MyDomainClass.getAll().contains(myDomainClass1); // false
        myDomainClass1.save(flush:true)
    
        def myDomainClass2 = new MyDomainClass( some: "bar", arbitrary: 1, field: true)
        assert MyDomainClass.getAll().contains(myDomainClass2); // false.  Even though this has the same `arbitrary` value as myDomianClass1, it has a different `some` value which makes it unique.
        myDomainClass2.save(flush:true)
    
        def myDomainClass3 = new MyDomainClass( some: "foo", arbitrary: 1, field: false)
        assert MyDomainClass.getAll().contains(myDomainClass3); // false.  Even though this has the same `some` value as myDomainClass1 and the same `arbitrary` value as myDomainClass1 and myDomainClass2, it has a different `field` value which makes it unique.
        myDomainClass3.save(flush:true)
    

1 个答案:

答案 0 :(得分:1)

这将确保域中3个字段的组合是唯一的。这也确保了约束在数据库级别,而不仅仅是应用程序级别。

class MyDomainClass {
    String some
    int arbitrary
    boolean field
    static constraints = {
        some(unique: ['arbitrary', 'field'])
    }
}