gpt4 book ai didi

hibernate - 刷新: true different from manually flushing the currentSession?是怎么回事

转载 作者:行者123 更新时间:2023-12-02 22:01:21 25 4
gpt4 key购买 nike

我有一个 GORM 对象,正在集成测试中使用。它有一个 beforeUpdate Hook ,用于保存之前密码哈希的历史记录。代码看起来像这样:

class Credentials {
List passwordHistory = []
String username
String password

static hasMany = [passwordHistory : String]

def beforeUpdate() {
// of course I'm not really storing plain-text passwords, but
// this is just for illustration.
if (isDirty('password')) { passwordHistory << password }
}
}

在集成测试中,我想知道为什么:

appUser.credentials.password = newPassword
appUser.save(flush: true)
sessionFactory.currentSession.flush()
AppUser.withNewSession {
appUser = AppUser.get(appUser.id)
appUser.credentials.empty // eagerly fetch the list while session is open
}
assert !appUser.credentials.passwordHistory.empty() // contains the previous password

有效,但是

appUser.credentials.password = newPassword
appUser.save()
sessionFactory.currentSession.flush()
AppUser.withNewSession {
appUser = AppUser.get(appUser.id)
appUser.credentials.empty // eagerly fetch the list while session is open
}
assert !appUser.credentials.passwordHistory.empty() // is empty

没有。不同之处在于 appUser.save() 调用中的 flush: true。我认为对 save() 的调用将对象附加到当前 session ,但刷新当前 session 不会将密码添加到 passwordHistory 列表中。这里到底发生了什么?

最佳答案

如果我正确解释 Grails 代码,那么您实际上正在处理两个不同的 session 。来自文档:

Integration tests run inside a database transaction by default, which is rolled back at the end of the each test. This means that data saved during a test is not persisted to the database.

如果您深入研究 Grails GORM 方法逻辑,您会发现当您处于事务中时,GORM 从 ThreadLocal 获取其 session 。由 TransactionSynchronizationManager 维护的资源 map 类(class)。如果找不到,它会打开一个新 session 并将其绑定(bind)到 map - 重要的区别是,它显式打开一个新 session 。它不只是调用sessionFactory.getCurrentSession() .

save() 的末尾GORM逻辑,如果你传入flush:true它将刷新与事务关联的 session - 它从 TransactionSynchronizationManager 中的资源映射中获取的 session 。 。

另一方面,当您调用flush()时您在从 sessionFactory.getCurrentSession() 获得的 session 中调用它我相信这是一个绑定(bind)到您的线程的 session CurrentSessionContext由 Hibernate 使用 SessionFactory 。实际执行CurrentSessionContext不是重点,因为(除非我缺少特定于 Grails 的实现)它不会返回由 TransactionSynchronizationManager 持有的相同 session 。 .

关于hibernate - 刷新: true different from manually flushing the currentSession?是怎么回事,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20410858/

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