gpt4 book ai didi

grails - 保存新的域对象会导致立即刷新

转载 作者:行者123 更新时间:2023-12-02 13:56:40 24 4
gpt4 key购买 nike

在 Controller 中保存新创建的域对象会导致立即刷新休眠 session 。 (我添加了sleep()以确保它不是日志记录问题,并且我用mysql-query.log再次检查了这些调用,而不仅仅是“打印”了)

5.times { i ->
new Foo(bar: "$i").save()
log.error("$i")
sleep(1000)
}

启用休眠查询日志后,这将导致
2013-12-11 15:26:41,593 [http-bio-8080-exec-6] DEBUG hibernate.SQL  - insert into foo (version, bar) values (?, ?)
| Error 2013-12-11 15:26:41,596 [http-bio-8080-exec-6] ERROR app.HomeController - 0
2013-12-11 15:26:42,600 [http-bio-8080-exec-6] DEBUG hibernate.SQL - insert into foo (version, bar) values (?, ?)
| Error 2013-12-11 15:26:42,605 [http-bio-8080-exec-6] ERROR app.HomeController - 1
2013-12-11 15:26:43,610 [http-bio-8080-exec-6] DEBUG hibernate.SQL - insert into foo (version, bar) values (?, ?)
| Error 2013-12-11 15:26:43,613 [http-bio-8080-exec-6] ERROR app.HomeController - 2
2013-12-11 15:26:44,618 [http-bio-8080-exec-6] DEBUG hibernate.SQL - insert into foo (version, bar) values (?, ?)
| Error 2013-12-11 15:26:44,622 [http-bio-8080-exec-6] ERROR app.HomeController - 3
2013-12-11 15:26:45,626 [http-bio-8080-exec-6] DEBUG hibernate.SQL - insert into foo (version, bar) values (?, ?)
| Error 2013-12-11 15:26:45,631 [http-bio-8080-exec-6] ERROR app.HomeController - 4

查看位于的grails文档
http://grails.org/doc/latest/ref/Domain%20Classes/save.html

The save method informs the persistence context that an instance should be saved or updated. The object will not be persisted immediately unless the flush argument is used:



对我来说,问题是:文档只是错误的还是错误?

问题(至少对我而言)是刷新了整个 session ,这可能会导致不必要的更改被保留。

我在grails-2.3.3和grails-2.2.4上复制了此代码,并使用最新的hibernate3和hibernate4插件进行了检查。所有配置组合的行为都相同,因此我想这是一个误导性文档,但我仍然想再次检查。

更新

根据sergio的要求,这个 super 简单的 Controller 将导致上述输出。
class HomeController {
def index(){
5.times { i ->
new Foo(bar: "$i").save()
log.error("$i")
sleep(1000)
}
}
}

最佳答案

您不会看到刷新,只是SQL比预期的要早。由于您看到的数据库 Activity 比您预期的要早,所以这有点麻烦,但是直到请求结束才进行显式刷新-您可以在调试器中或启用日志记录的情况下看到它。

您会看到,Hibernate需要执行插入操作才能检索自动生成的ID。因此,它为每个save()调用进行了显式插入,但是在请求的末尾只有一个真正的刷新,由OpenSessionInView拦截器触发。

因此,文档有些偏离。在新的非持久实例上调用save()将触发数据库插入,但不会刷新。在经过修改的持久性实例上调用save()或在持久性实例上调用delete()不会触发数据库更新,除非进行显式刷新或Hibernate检测到需要更新(例如)。如果您进行查询,则可能会受到未刷新数据的影响。

编辑

这是一个更大的例子来说明正在发生的事情。首先,我创建2个Foos并刷新这些保存。然后,我编辑并保存一个,然后删除另一个,都没有刷新。我对5个新实例进行了相同的创建,并查看了它们的SQL,但没有更新或删除实例,因为还没有刷新。最后,当我进行显式刷新时,您会看到这两个SQL语句:

class HomeController {

def index() {

def toEdit = new Foo(bar: 'editme').save()
def toDelete = new Foo(bar: 'deleteme').save(flush: true)
println 'created first 2 and flushed'

toEdit.bar += '_edited'
toEdit.save()
toDelete.delete()
println 'edited one, deleted one'

5.times { i ->
new Foo(bar: "$i").save()
println "created foo $i"
sleep 1000
}
println "created 5"

println "before explicit flush"
Foo.withSession { it.flush() }
println "after explicit flush"
}
}

这是输出:
2013-12-11 12:46:20,120 [http-bio-9090-exec-1] DEBUG hibernate.SQL  - insert into foo (id, version, bar) values (null, ?, ?)
2013-12-11 12:46:20,138 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created first 2 and flushed
edited one, deleted one
2013-12-11 12:46:20,188 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created foo 0
2013-12-11 12:46:21,197 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created foo 1
2013-12-11 12:46:22,202 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created foo 2
2013-12-11 12:46:23,211 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created foo 3
2013-12-11 12:46:24,219 [http-bio-9090-exec-1] DEBUG hibernate.SQL - insert into foo (id, version, bar) values (null, ?, ?)
created foo 4
created 5
before explicit flush
2013-12-11 12:46:25,282 [http-bio-9090-exec-1] DEBUG hibernate.SQL - update foo set version=?, bar=? where id=? and version=?
2013-12-11 12:46:25,284 [http-bio-9090-exec-1] DEBUG hibernate.SQL - delete from foo where id=? and version=?
after explicit flush

关于grails - 保存新的域对象会导致立即刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20522320/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com