为什么在 GORM 中只读访问正在写入我的数据库?

发布于 2024-12-07 09:13:15 字数 728 浏览 0 评论 0原文

在我的应用程序中,我有这样的代码:

// 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() 也有效)

文档:http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html#5.1.1%20Basic%20CRUD

(在第一种情况,我想我犯了错​​误)

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)

Doc: http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html#5.1.1%20Basic%20CRUD

(In the first case, I guess I made mistest)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

波浪屿的海角声 2024-12-14 09:13:15

两者都应该保存,因此第一个示例似乎是一个错误。 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文