4

我正在“事务化”一些广泛的数据库操作,我遇到了这个问题,如果我通过 hibernate 运行 sql 查询但不使用 MQL 方法,数据库的视图看起来不正确。具体来说,代码在大多数情况下以更合适的方式使用休眠,但有些地方有人决定只执行 sql。我不喜欢他们这样做,但在这一点上“就是这样”。

我找到了一个似乎可以解释它的解释,但所有示例实际上都是在代码中获取和管理事务。我们在整个类上使用@TransactionAttribute 注释来更改此代码,并且发现了很多发生这种行为的地方,但我并不完全相信该解释适用于简单地包装在注释中的代码——我假设任何使用休眠管理器的东西都将依赖于会话中的对象缓存。

如果我用不正确的术语等来指代休眠中的概念,请提前道歉。

4

2 回答 2

9

实际上,Chris Landry 的“解释”博客错过了 SQLQuery 的 3 个重要 API 方法,这就是他遇到这些问题的原因。具体来说,(1) addSynchronizedQuerySpace,(2) addSynchronizedEntityName 和 (3) addSynchronizedEntityClass

正如 partenon 所指出的,仅仅基于 SQL 查询字符串本身,Hibernate 无法知道查询中查询了哪些表和/或实体。因此,它不知道 Session 中排队的哪些更改需要刷新到数据库。在博客中,Chris 确实指出您可以在运行 SQL 查询之前自行执行 flush() 调用。但是,我所描述的是 Hibernate 的自动刷新功能。它实际上对 HQL 和 Criteria 查询做同样的事情。只有在那里它知道受到影响的表。无论如何,这个自动刷新过程会执行“最小刷新”,仅刷新影响查询的内容。这就是这些方法发挥作用的地方。

例如,Chirs 的 SQL 查询是

session.createSqlQuery("select name from user where name = :userName")

他真正需要做的就是说……

session.createSqlQuery("select name from user where name = :userName")
        .addSynchronizedQuerySpace( "user" )

addSynchronizedQuerySpace( "user" )告诉 Hibernate 查询使用了一个名为“user”的表。现在 Hibernate 可以自动刷新映射到该用户表的实体的所有未决更改。

于 2012-05-31T06:01:47.130 回答
7

您的问题令人困惑,但我假设您是说当您执行本机查询时,Hibernate 不会在会话缓存中查找实体。

SQL Query 或 Native Query 是 Hibernate 仅中继到数据库的查询。Hibernate 不会解析查询,也不会解析结果。不过,Hibernate 会让您处理结果,将列转换为类的属性。也就是说,Native Queries 绕过 Session 缓存听起来很自然。那是因为 Hibernate 对您的查询一无所知,也不知道该查询的“结果”(当时还不是对象)。

于 2010-12-21T14:27:46.583 回答