考虑以下域类:
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。
提前感谢您的帮助。
答案 0 :(得分:0)
这只是一个猜测,但可能是一个开始的地方。当Hibernate决定刷新会话并部分保存数据等时,我不会假装理解。但我所知道的是,随着时间的推移,将所有与写相关的电话放在一项服务中会让我感到悲痛。
尝试将一些更新方法移至服务中,看看您是否有更好的运气。我的预感是,hibernate可能需要保留一些数据来执行其他操作,如果它是在事务服务中,那么一旦抛出RuntimeException,该写操作就会回滚。
答案 1 :(得分:0)
我建议使用服务保存您的对象。首先,使用validate()方法检查所有对象的有效性。
然后,按照它们所依赖的顺序或它们所遵循的层次结构保存对象。