在自己的域上进行 Grails 验证
Posted
技术标签:
【中文标题】在自己的域上进行 Grails 验证【英文标题】:Grails validation over own domain 【发布时间】:2015-08-18 22:48:18 【问题描述】:我正在使用 Grails 2.4.2 并且有一个类 Contract,其中包含许多 InvoiceRecipient。 InvoiceRecipients 类有一个属性 invoiceType,它有 2 个可能的值,'O' 用于发票原件,'C' 用于发票-复制。您可以想象,对于一份合同,InvoiceRecipients 只允许一条类型为 'O' 的记录。
如果我尝试按照以下代码片段来实现它,VM 会运行到 ***。
我尝试的另一种方法是一种服务方法,它遍历合同的收件人数组以计算 invoiceType 为“O”的记录,或者我尝试通过 InvoiceRecipient.countByContractAndInvoiceType() 进行选择计数以确定“O”的数量在控制器中的contract->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 ***
if (InvoiceRecipient.countByContractAndInvoiceType(obj.contract, 'O') > 1)
return "invoiceRecipient.original.max.exceed"
*/
【问题讨论】:
【参考方案1】:我可能会使用这样的东西:
validator: val, obj ->
if (obj.recipients.findAllinvoiceType == 'O'.size() > 1)
return "invoiceRecipient.original.max.exceed"
这样您应该能够防止 Hibernate 尝试刷新脏对象并在此过程中重新验证该对象。
【讨论】:
啊,太好了,就像一个魅力!我很少使用 find-Methods... 我唯一需要更改的是 **it.**invoiceType == 'O'。以上是关于在自己的域上进行 Grails 验证的主要内容,如果未能解决你的问题,请参考以下文章