【问题标题】:grails domain object unexpectedly saved during validationgrails 域对象在验证期间意外保存
【发布时间】:2012-06-11 09:33:14
【问题描述】:

考虑以下领域类:

class EnrichmentConfig {

    String name
    String description
    String concept
    List fields = []

    static hasMany = [fields: FieldConfig]

    static constraints = {
        name(maxSize: 60, blank: false, nullable: false, unique: true)
        concept(maxSize: 255, blank: false, nullable: false)
        description(nullable: true, blank: true)
        fields(nullable: false, validator: { fields, enrichmentConfig ->
            if (fields?.isEmpty()) {
                return ['empty']
            } else {
                return true
            }
        })
    }

    static mapping = {
        description(type: 'text')
        fields(cascade: "all-delete-orphan")

        sort('name')
    }
}

class FieldConfig {

    List providers = []

    static hasMany = [providers: String]

    static belongsTo = [mainConfig: EnrichmentConfig]

    static constraints = {

        providers(nullable: false, validator: { providers, fieldConfig ->
            // some custom validation
        })
    }

    static mapping = {
        providers(cascade: 'all-delete-orphan', lazy: false)
    }
}

这里是我用来更新关联控制器中EnrichmentConfig 实例的代码:

def update = {

    def enrichmentConfig = EnrichmentConfig.get(params.long('id'))
    if (enrichmentConfig) {

        enrichmentConfig.properties = params

        if (enrichmentConfig.validate()) {
            if (enrichmentConfig.save(flush: true, failOnError: true)) {
                    flash.message = "${message(code: 'enrichmentConfig.updated.message', args: [enrichmentConfig.name])}"
                    redirect(controller: 'enrichment')
                }
        } else {
            // re-validation to attach an error object to each eroneous fieldConfig
            enrichmentConfig.fields?.each { it.validate() }
        }
        render(view: 'fields', model: getFieldsModel(enrichmentConfig))
        return
    } else {
        flash.message = "${message(code: 'enrichmentConfig.not.found.message', args: [params.id])}"
        redirect(controller: 'enrichment')
    }
}

我注意到,当我验证要更新的 EnrichmentConfig 实例时,关联的 FieldConfig 实例会意外保存在数据库中,即使它们是无效的。 事实上,在 debug ste-by-step 模式下,在执行enrichmentConfig.validate() 的同时,控制台中会出现以下内容:

    Hibernate: 
    update
        field_config_providers 
    set
        providers_string=? 
    where
        field_config_id=? 
        and providers_idx=?

这怎么会发生?我究竟做错了什么? 我应该指定我使用 grails 1.3.7。

提前感谢您的帮助。

【问题讨论】:

  • // some custom validation 在您的代码中实际上是空的,还是您在此处发布时将其遗漏了?动态查找器调用 (Something.findAllByFoo(...)) 之类的某些事情会触发会话刷新,因此如果您在验证器中使用类似的东西,请小心。

标签: validation grails grails-orm grails-domain-class grails-validation


【解决方案1】:

这只是一个猜测,但可能从某个地方开始。当 Hibernate 决定刷新会话并部分保存数据等时,我不会假装理解。但我所知道的是,将所有与写入相关的调用放在一个服务中可以为我节省大量时间。

尝试将一些更新方法转移到服务中,看看是否有更好的运气。我的预感是,hibernate 可能需要保留一些数据来做其他事情,如果它在事务服务中,一旦抛出 RuntimeException,写入就会回滚。

【讨论】:

    【解决方案2】:

    我建议使用服务来保存您的对象。首先,使用 validate() 方法检查所有对象的有效性。

    然后,按照对象依赖的顺序或遵循的层次结构保存对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-06
      • 2015-01-06
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多