我正在使用Grails 2.4.2,并且有一个包含许多InvoiceRecipient的Contract类。 InvoiceRecipients类具有一个属性invoiceType,该属性具有2个可能的值,“O”代表原始发票,“C”代表发票副本。可以想象,一个契约(Contract)的InvoiceRecipients只允许输入一个类型为“O”的记录。
如果我尝试按照下面的代码片段实现它,则VM会运行到StackOverflow中。
我尝试的另一种方法是一种服务方法,该方法遍历契约(Contract)的收件人数组以对具有invoiceType'O'的记录进行计数,或者我尝试通过InvoiceRecipient.countByContractAndInvoiceType()进行选择计数以确定契约(Contract)中'O'的数量-> Controller 中的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"
*/
}
}
最佳答案
我可能会用这样的东西:
validator: { val, obj ->
if (obj.recipients.findAll{invoiceType == 'O'}.size() > 1)
return "invoiceRecipient.original.max.exceed"
这样,您应该能够防止Hibernate尝试刷新脏对象并在此过程中重新验证该对象。
关于hibernate - 通过自己的域进行Grails验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30641900/