And*_*zer 7 grails hibernate flush save
在将我的Grails项目从1.3.7升级到2.4.0之后,在修复了与新grails版本相关的各种问题后,我意识到除了save(flush:true)被调用之外,对任何对象所做的任何更改都不会再存在(根本没有).
使用Grails 1.3.7时,使用域实例保存时的默认行为save()是,由于hibernate flushMode =>,更改会自动保留FlushMode.AUTO.在Grails 2.4.0中,这不再适用.任何控制器操作或服务类内的hibernate会话的默认flushMode是FlushMode.MANUAL.
sessionFactory.currentSession.flushMode在BootStrap中检索时,事情变得更加奇怪,它FlushMode.AUTO在控制器操作中具有值,并且具有值FlushMode.MANUAL.这可以通过创建新的grails应用程序并放入println "flushMode = $sessionFactory.currentSession.flushMode"BootStrap和控制器操作(例如index())来验证.
我在过去的两天里一直在搜索所有类型的论坛,但没有找到任何合理的解释,为什么必须在Grails 2.4.0(或者甚至是早期版本)中更改它.我只发现评论说它有风险,FlushMode.MANUAL因为在修改了其他一些文件后,你可能会遇到陈旧的对象.
我知道:
grails.gorm.autoFlush = true在配置你可以强制刷新:真实每次保存()FlushMode.AUTO
hibernate.flush.mode = 'auto'
hibernate.flushMode = 'auto'
hibernate.session.flush.mode = 'auto'
hibernate.session.flushMode = 'auto'
dataSource.hibernate.flush.mode = 'auto'
dataSource.hibernate.flushMode = 'auto'
dataSource.hibernate.session.flush.mode = 'auto'
dataSource.hibernate.session.flushMode = 'auto'
dataSource.flush.mode = 'auto'
dataSource.flushMode = 'auto'
dataSource.session.flush.mode = 'auto'
dataSource.session.flushMode = 'auto'请问有人可以点一点吗?
实际上我想知道Grails 2.4.0 FlushMode.MANUAL现在是否是理想的默认值?
如果是这样:
非常感谢 - 安迪
在阅读Graemes Answer和他的评论后,我试图更好地阐明我正在努力解决的问题,并添加了以下简化的域和控制器类来演示这种行为:
域类消息:
class Msg {
String text
static constraints = {
text nullable:true
}
}
Run Code Online (Sandbox Code Playgroud)
和msg控制器:
class MsgController {
def sessionFactory
def index = {
def out = ["*** flushMode when in controller/index = \
$sessionFactory.currentSession.flushMode"]
Msg.list().each { out << "$it.id: text=$it.text" }
render out.join('<br>')
}
// this save does persist the new msg object,
// even if flushMode = MANUAL
def save1 = {
def out = ["*** flushMode when in controller/save = \
$sessionFactory.currentSession.flushMode"]
def msg = new Msg(text:'hallo')
if (!msg.save()) {
out << "msg has errors! " + msg.errors
}
out << "msg $msg.id created with text = $msg.text"
render out.join('<br>')
}
// this save does NOT persist the new msg object, even if its valid
// (difference is calling hasErrors()
def save2 = {
def out = ["*** flushMode when in controller/save = \
$sessionFactory.currentSession.flushMode"]
def msg = new Msg(text:'hallo')
if (msg.hasErrors() && !msg.save()) {
out << "msg has errors! " + msg.errors
}
out << "msg $msg.id created with text = $msg.text"
render out.join('<br>')
}
}
Run Code Online (Sandbox Code Playgroud)
所以调用http://localhost/appname/msg/save1输出是:
*** flushMode when in controller/save1 = MANUAL
msg 1 created with text = hallo
Run Code Online (Sandbox Code Playgroud)
在这里我不明白,为什么hibernate持久化对象,即使你的flushMode是MANUAL.
当调用http://localhost/appname/msg/save2输出时:
*** flushMode when in controller/save2 = MANUAL
msg null created with text = hallo
Run Code Online (Sandbox Code Playgroud)
该对象不会被持久化,因为hibernate不会发出flush,因此永远不会调用sql"update ..."命令.
但现在似乎不仅flushMode是一个问题,而且如果一个人调用hasErrors()或者不是!我更困惑的是......
如果您在Grails 1.3.7中执行此示例,则保存操作(save1和save2)会保留新创建的msg对象!
Grails会在验证之前将刷新模式设置为手动,以防止在验证期间刷新任何更改(这可能非常常见,因为您可能有一个查询现有数据的自定义验证器).
如果存在任何验证错误,则不会将刷新模式设置回AUTO.这是为了防止无效对象被持久化.
您所看到的是您可能发生了验证错误,虽然您可以强制刷新,但这是不可取的.
| 归档时间: |
|
| 查看次数: |
4790 次 |
| 最近记录: |