Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate grails中的刷新模式从自动更改为手动_Hibernate_Grails_Save_Flush - Fatal编程技术网

Hibernate grails中的刷新模式从自动更改为手动

Hibernate grails中的刷新模式从自动更改为手动,hibernate,grails,save,flush,Hibernate,Grails,Save,Flush,在将我的Grails项目从1.3.7升级到2.4.0并解决了与新Grails版本相关的各种问题之后,我意识到对任何对象所做的更改都不会再被持久化(根本),除非调用了save(flush:true) 对于Grails 1.3.7,使用save()保存域实例时的默认行为是,由于hibernate flushMode=>flushMode.AUTO,更改会自动持久化。在Grails2.4.0中,这不再是事实。任何控制器操作或服务类中hibernate会话的默认刷新模式为flushMode.MANUAL

在将我的Grails项目从1.3.7升级到2.4.0并解决了与新Grails版本相关的各种问题之后,我意识到对任何对象所做的更改都不会再被持久化(根本),除非调用了
save(flush:true)

对于Grails 1.3.7,使用
save()
保存域实例时的默认行为是,由于hibernate flushMode=>
flushMode.AUTO
,更改会自动持久化。在Grails2.4.0中,这不再是事实。任何控制器操作或服务类中hibernate会话的默认刷新模式为
flushMode.MANUAL

在BootStrap中检索
sessionFactory.currentSession.flushMode
时,情况变得更加奇怪,它的值为
flushMode.AUTO
,在控制器操作中,它的值为
flushMode.MANUAL
。这可以通过创建一个新的grails应用程序并将
println“flushMode=$sessionFactory.currentSession.flushMode”
放入引导和控制器操作(例如index())来验证

在过去的两天里,我一直在搜索各种论坛,没有找到任何合理的解释来解释为什么必须在Grails2.4.0(甚至可能在更早的版本中)中对此进行更改。我只发现一些评论说,使用
FlushMode.MANUAL
有点冒险,因为在修改了其他对象之后,在查询数据库时可能会遇到过时的对象

我知道:

  • 在配置中使用
    grails.gorm.autoFlush=true
    可以强制刷新:true到每个save()
  • 在hibernate3和hibernate4中,默认的flushMode是
    flushMode.AUTO
  • 无法在Config.groovy或DataSource.groovy中设置flushMode。我尝试了所有这些,但都没有成功:
    
    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'
有人能帮我照一下吗

实际上,我想知道Grails2.4.0
FlushMode.MANUAL
中的默认值是否是现在所需的

若有:

  • 彼得·莱德布鲁克(Peter Ledbrook)在年发表的评论“…建议不是我们完全禁用自动刷新模式…”是什么意思
  • 最好的做法是避免遇到过时对象的问题,特别是在对域对象执行复杂操作时,其中修改、创建新实例和查询都是混合的
非常感谢 -安迪


在阅读Graemes的答案和他的评论后,我试图更好地澄清我正在努力解决的问题,并添加了以下简化的域和控制器类,以演示该行为:

域类消息:

class Msg{
字符串文本
静态约束={
文本可为空:true
}
}
以及msg控制器:

class MsgController{
def会话工厂
def索引={
def out=[“***在控制器/索引中时刷新模式=\
$sessionFactory.currentSession.flushMode“]

Msg.list()。每个{outGrails将在验证之前将刷新模式设置为手动,以防止在验证期间刷新任何更改(这可能非常常见,因为您可能有一个查询现有数据的自定义验证器)

如果存在任何验证错误,它将不会将刷新模式设置回自动。这是为了防止无效对象被持久化


您看到的是,您可能出现了验证错误,尽管您可以强制刷新,但这是不可取的。

感谢您的解释。这是有意义的。但是,为什么Grails在控制器操作中切换到手动,即使没有保存域对象(根本不用)?我编写了一个只有一个控制器的小型Grails应用程序,没有域类来验证这一点。在控制器索引操作中,我只放了一个LOC
println“flushMode=$sessionFactory.currentSession.flushMode”
对于读取操作,Grails使用只读事务。只读事务使用手动刷新模式。读取操作使用只读事务的原因是因为它提高了性能,因为Hibernate不需要脏检只读对象。这可能就是您看到的。请参阅更新域和c的原始问题OnController示例您的第二个示例毫无意义,因为执行
if(msg.hasrerrors()&&&!msg.save())
意味着永远不会调用
save()
,因为
hasrerrors()
将返回
false
对不起,我的打字错误!应该是
if(msg.hasrerrors()| | msg.save())
然后这两个操作都会保留msg对象,而上面的整个示例毫无意义!我必须检查有问题的代码,并尝试提取它以使问题可见。。。