我正在将Grails应用程序从Oracle移植到MySQL数据库。最初的Oracle版本是一个遗留数据库,它使用一些复杂的视图,利用Oracle没有的Oracle INSTEAD OF INSERT OR UPDATE功能。作为一种解决方法,我在Domain类上实现了Insert和Update方法,这些方法指向了这些类型的视图。例如,
class AdminUser {
//...
def update() {
if(this.validate()) {
Sql sql = Utils.getHibernateSql()
sql.execute(
"update table_x ...",
[...]
)
sql.execute(
"update table_y ...)",
[...]
)
sql.execute(
"update table_z ...",
[...]
)
return true
}
return false
}
//...
}
以下是我正在遇到的问题的描述:
如何防止在步骤(3)中发生神奇的保存(我最近在某处读到Grails会自动保存一个修改后的Domain类实例,该实例在退出服务方法时尚未保存,但我似乎无法看到现在找到该资源的链接)?
答案 0 :(得分:2)
您将使用脏字段将已修改的实例保留在hibernate会话中。当hibernate会话被刷新时,它会尝试使用通常的save()
方法再次保存对象。
一种解决方案是在手动保存更改后从休眠会话中丢弃对象。例如:
def update() {
if(this.validate()) {
Sql sql = Utils.getHibernateSql()
sql.execute(
"update table_z ...",
[...]
)
...
this.discard() // remove the object from the hibernate session
return true
}
此外,您可以将其添加到Config.groovy以要求明确保存对象:
hibernate.flush.mode="manual"
答案 1 :(得分:0)
如果使用read()而不是get(),则对象不会自动保持更改。您仍然可以显式调用save(),但OpenSessionInView拦截器刷新所有未保存的脏实例的标准行为将跳过使用read()加载的实例。