hibernate - 通过自己的域进行Grails验证

标签 hibernate grails grails-domain-class grails-controller grails-validation

我正在使用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/

相关文章:

java - 无法找到命名参数

grails - 如何设置基于hasMany关系的唯一类属性?

hibernate - 扩展域类导致奇怪的表布局和不可访问的字段

grails - grails 中的重复错误消息

mysql - 将 Grails 与 PostgreSQL 一起使用时出现 org.hibernate.StaleObjectStateException

grails - 如何在一个域类中混合 'Reference' 和 'No Reference' 属于关系?

java - Hibernate无法正确操作多个包

Java hibernate如何使用注解映射继承

java - 为什么外键的值总是为零?

grails - Grails-全局通用的制作方法和元类编程