Hibernate SQLQuery绕过了hibernate会话缓存

时间:2010-12-21 14:19:30

标签: hibernate jboss transactional

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

我发现explanation似乎解释了它,但所有的例子都是在代码中实际获取和管理事务。我们在整个类上使用@TransactionAttribute注释来更改此代码,并且发现了许多发生此行为的地方,但我并不完全相信这些解释适用于简单地包含在注释中的代码 - 我假设任何使用hibernate管理器的东西都会依赖于会话中的对象缓存。

如果我通过不正确的术语等提及hibernate中的概念,请提前道歉

2 个答案:

答案 0 :(得分:8)

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

正如partenon指出的那样,仅基于SQL查询字符串本身,Hibernate无法知道查询中查询了哪些表和/或实体。因此,它不知道会话中排队的更改需要刷新到数据库。在博客中,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可以自动清除映射到该用户表的实体的所有未决更改。

答案 1 :(得分:7)

您的问题令人困惑,但我认为您在执行Native查询时,Hibernate并未在Session缓存中查找实体。

SQL Query或Native Query是Hibernate只传递给数据库的查询。 Hibernate不会解析查询,也不会解析结果。但是,Hibernate会让你处理结果,将列转换为类的属性。也就是说,Native Queries绕过Session缓存听起来很自然。那是因为Hibernate不知道你的查询,也不知道这个查询的“结果”(当时不是对象)。

相关问题