0

我使用的是Grails 2.4.2並擁有類別合同其中有很多InvoiceRecipient的。 InvoiceRecipients類有一個屬性invoiceType它有兩個可能的值,'O'爲發票原件和'C'爲發票副本。如您所見,只有一個類型爲'O'的記錄可用於一份合同的InvoiceRecipients。對自己域名的Grails驗證

如果我嘗試像下面的snipplet一樣實現它,VM將運行到StackOverflow中。

我嘗試的另一種方法是迭代通過合約的收件人數組來計算具有invoiceType'O'的記錄的服務方法,或者我試圖通過InvoiceRecipient.countByContractAndInvoiceType()來確定「 O在控制器中的合同 - > invoiceRecipients關係中。

在最後兩種情況下,Hibernate爲我當前的InvoiceRecipient記錄生成一個更新語句,我嘗試驗證它。即使當前InvoiceRecipient的驗證失敗,並填充實例的錯誤對象,該記錄也已更新(沒有問題,因爲約束不會編碼到類中,並在「保存」中不會引發錯誤)。我在數據庫中有邏輯錯誤的記錄。

class Contract implements Serializable { 
    ... 
    static hasMany = [recipients: InvoiceRecipient] 
    ... 
} 

class InvoiceRecipient implements Serializable { 
    static belongsTo = [contract: Contract] 
    ... 
    String invoiceType 
    ... 

    static constraints = { 
     invoiceType nullable: false, maxLength: 1, inList: ['O', 'C'], validator: { val, obj -> 
     /* => This generates a StackOverflow 
     if (InvoiceRecipient.countByContractAndInvoiceType(obj.contract, 'O') > 1) 
      return "invoiceRecipient.original.max.exceed" 
     */ 
    } 
} 

回答

1

我可能會使用這樣的:

validator: { val, obj -> 
if (obj.recipients.findAll{invoiceType == 'O'}.size() > 1) 
     return "invoiceRecipient.original.max.exceed" 

這樣,你應該能夠防止從休眠試圖清除骯髒的對象,並在這個過程中重新驗證這個對象。

+0

啊,這太棒了,就像一個魅力!我很少使用find-Methods ...我必須改變的唯一方法是**。invoiceType =='O'。 – susi