Grails 验证域类的实例是否唯一

Grails 验证域类的实例是否唯一,grails,Grails,我有一个Grails应用程序,它有一堆域类,一些域类有很多字段,其中一些域类与所讨论的域类有很多关系。对于这个特定的应用程序,我只有一个“约束”,即每个域类的每个实例都必须是唯一的。我不在乎一个任意字段在同一个域类的多个实例中是否具有相同的值,只要该域类中的某个其他字段的值使每个实例都是唯一的。因此,基本上我希望验证在域类实例级别而不是域类字段级别进行。现在,我通过使用groovy@EqualsAndHashCode注释来生成我的equals和hashCode方法,然后在域类的某个任意字段上的自

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

两个问题:

  • 是否有更有效的方法验证域类是否唯一
  • 如果没有,那么是否有一种方法可以在域类实例本身上调用自定义验证程序代码,而不是遍历域类实例的某个字段

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

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

    很难理解你在问什么。您想知道域类是否唯一,但不在字段级别。除域的字段外,您如何确定它是否唯一?你能不能说
    任意唯一:true
    ???在这种情况下,提供您正在使用的实际示例会有所帮助。@JamesKleeh如果我说
    arbitral unique:true
    ,这意味着该
    MyDomainClass
    的任何其他实例中的任何
    arbitral
    字段都不能具有相同的值。那不是我想要的。我希望
    MyDomainClass
    的其他实例能够具有完全相同的
    任意值,只要其他字段的值使域类的实例唯一。我将添加一个更好的示例来说明这一点。因此,您需要添加一个跨越所有字段的唯一约束<代码>一些唯一的:[“任意”,“字段”]
    @JamesKleeh如果我使用多列
    唯一的
    (我想这就是你所建议的),我将不得不对
    MyDomainClass中的每个字段都这样做。示例:
    some(唯一:['arbic',field']
    然后
    arbic(唯一:['some',field'])
    然后
    field(唯一:['some',arbic'])
    。我很确定这会满足我的需求(而且肯定比我现在做的更有效),但如果可能的话,我希望有一个更通用的解决方案。您只需要在一个字段上设置约束。我上面展示的示例将确保“某些”、“任意”和“字段”将是唯一的键。您的三个示例都做了完全相同的事情,您设置的顺序和字段是……任意:)我将尝试一下。我曾经测试过一次(过去在不同的应用程序上),我记得它的工作方式不同。希望我是错的:)这看起来像你想象的那样有效。我想我让事情变得比实际更难了:/
        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)
    
    class MyDomainClass {
        String some
        int arbitrary
        boolean field
        static constraints = {
            some(unique: ['arbitrary', 'field'])
        }
    }