为什么在 GORM 中只读访问正在写入我的数据库?
在我的应用程序中,我有这样的代码:
// 1
Foo.get(123).example = "my example" // as expected, don't change value in db
// 2
Foo.get(123).bars.each { bar ->
bar.value *= -1 // it's changing "value" field in database!! WHY?
}
- 注意:Foo 和 Bar 是我的数据库中的表
为什么 gorm 保存在数据库中是第二种情况? 我的代码中没有任何 save() 方法。
谢谢
已解决: 我需要使用 read()
来获取只读会话。 (Foo.discard() 也有效)
(在第一种情况,我想我犯了错误)
In my app, I have a code like this:
// 1
Foo.get(123).example = "my example" // as expected, don't change value in db
// 2
Foo.get(123).bars.each { bar ->
bar.value *= -1 // it's changing "value" field in database!! WHY?
}
- note: Foo and Bar are tables in my DB
Why is gorm saving in database is second case?
I don't have any save() method in code.
Tks
SOLVED:
I need to use read()
to get a readonly session.
(Foo.discard() also works)
(In the first case, I guess I made mistest)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
两者都应该保存,因此第一个示例似乎是一个错误。 Grails 请求在 OpenSessionInView 拦截器的上下文中运行。这会在每个请求开始时打开一个 Hibernate 会话并将其绑定到线程,并在请求结束时刷新并关闭它。这对延迟加载有很大帮助,但可能会产生意想不到的后果,就像您所看到的那样。
尽管您没有显式保存,但 Hibernate 刷新中的逻辑涉及查找所有已修改的附加实例并将更新推送到数据库。这是一种性能优化,因为如果每次更改都被推送,就会减慢速度。所以所有可以等到刷新的东西都排队了。
因此,您唯一需要显式保存的时间是新实例以及您想要检查验证错误时。
Both should save, so the first example appears to be a bug. Grails requests run in the context of an OpenSessionInView interceptor. This opens a Hibernate session at the beginning of each request and binds it to the thread, and flushes and closes it at the end of the request. This helps a lot with lazy loading, but can have unexpected consequences like you're seeing.
Although you're not explicitly saving, the logic in the Hibernate flush involves finding all attached instances that have been modified and pushing the updates to the database. This is a performance optimization since if each change had been pushed it would slow things down. So everything that can wait until a flush is queued up.
So the only time you need to explicitly save is for new instances, and when you want to check validation errors.