2013-08-17 54 views
0

我有一大堆域類的Grails應用程序,其中一些域具有許多字段,其中一些與所討論的域類具有hasMany關係。對於這個特定的應用程序,我只有一個「約束」,那就是每個域類的每個實例都必須是唯一的。我不關心一個任意字段在同一個域類的多個實例中是否具有相同的值,只要每個實例由該域類中某個其他字段的值唯一確定即可。所以基本上我想驗證發生在域類實例級別而不是域級別字段級別。現在我正在使用非常規的@EqualsAndHashCode註釋來生成我的equalshashCode方法,然後在域類的某個任意字段的自定義驗證器中調用equals驗證域類的實例是唯一的

兩個問題:

  1. 是否有驗證域類是唯一的一個更有效的方法?
  2. 如果否,那麼是否有辦法在域類實例本身上調用我的自定義驗證器代碼,而不是通過域類實例的其中一個字段?
 
@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

@JamesKleeh如果我說「任意唯一:真」,這意味着任何其他'MyDomainClass'實例中的其他'任意'字段都不會具有相同的值。這不是我想要的。我希望其他實例的MyDomainClass能夠具有完全相同的「任意」值,只要其他字段的值使域類的實例唯一。我將添加一個更好的例子來說明這一點。 – ubiquibacon

+0

那麼你需要添加一個跨越所有字段的唯一約束。 '一些獨特的:['任意','字段']' –

回答

1

這將確保在域中的3場的組合是唯一的。這也確保了約束在數據庫級別,而不僅僅是應用程序級別。

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

我會試試這個。我測試過一次(過去在不同的應用程序上),我記得它的工作方式不同。希望我錯了:) – ubiquibacon

+0

這看起來像你想象的那樣工作。猜猜我正在變得比實際上更難:/ – ubiquibacon