我使用的是Grails 2.4.2,并且有一个合同,其中有很多 InvoiceRecipient&#39>。。 InvoiceRecipients类具有属性 invoiceType ,其中包含两个可能的值,' O' 用于发票原件和' C&# 39; 用于发票复印件。您可以想象,对于一份合同,InvoiceRecipients只允许使用类型为' O' 的一条记录。
如果我尝试按照以下snipplet实现它,则VM会运行到StackOverflow。
我尝试的另一种方法是一种服务方法,它迭代合同的收件人数组,用invoiceType' O'来计算记录。或者我尝试通过InvoiceRecipient.countByContractAndInvoiceType()进行选择计数,以确定控制器中合同 - > invoiceDecipients关系中的'
在最后两种情况下,Hibernate为我当前的InvoiceRecipient记录生成一个更新语句,我尝试对其进行验证。即使当前InvoiceRecipient的验证失败并且我填充了实例的errors-object,记录也已经更新(没有问题,因为约束没有编码到类中并且在&#34中没有引发错误;保存&# 34;。)我在数据库中有逻辑错误的记录。
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"
*/
}
}
答案 0 :(得分:1)
我可能会使用这样的东西:
validator: { val, obj ->
if (obj.recipients.findAll{invoiceType == 'O'}.size() > 1)
return "invoiceRecipient.original.max.exceed"
这样你就可以防止Hibernate尝试刷新脏对象,并在此过程中重新验证这个对象。