Объект домена Grails неожиданно сохранен во время проверки

Учитывая следующие классы предметной области:

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 неожиданно сохраняются в базе данных, даже если они недействительны. На самом деле, в пошаговом режиме отладки, пока выполняется enrichmentConfig.validate(), в консоли появляется следующее:

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

Как это может происходить? Что я делаю неправильно? Я должен указать, что я использую Grails 1.3.7.

Заранее спасибо за помощь.


person Jean-Louis Jouannic    schedule 07.06.2012    source источник
comment
Является ли // some custom validation действительно пустым в вашем коде или вы просто пропустили его при размещении здесь? Есть определенные вещи, такие как вызовы динамического поиска (Something.findAllByFoo(...)), которые запускают сброс сеанса, поэтому будьте осторожны, если вы используете что-то подобное в своем валидаторе.   -  person Ian Roberts    schedule 08.06.2012


Ответы (2)


Это всего лишь предположение, но, возможно, с чего-то начать. Я не претендую на понимание, когда Hibernate решает сбросить сеансы и частично сохранить данные и тому подобное. Но что я знаю точно, так это то, что размещение всех вызовов, связанных с записью, в службу избавляет меня от уймы горя с течением времени.

Попробуйте перенести часть своего метода обновления в службу и посмотрите, повезет ли вам больше. Я предполагаю, что, возможно, спящему режиму необходимо сохранять некоторые данные, чтобы выполнять другие действия, и если бы он был в транзакционной службе, эта запись откатилась бы после создания исключения RuntimeException.

person Gregg    schedule 07.06.2012

Предлагаю воспользоваться сервисом для сохранения ваших объектов. Сначала проверьте все объекты на валидность с помощью метода validate().

Затем сохраните объекты в том порядке, в котором они зависят, или в той иерархии, которой они следуют.

person sanghavi7    schedule 29.01.2013