Hibernate SQLQuery 绕过 Hibernate 会话缓存

发布于 2024-10-08 15:23:20 字数 479 浏览 3 评论 0原文

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

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

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

I'm "transactionalizing" some extensive database manipulation and I came across this issue where if I run sql queries through hibernate but not using the MQL approach, the view of the database doesn't appear correct. Specifically the code uses the hibernate in the more appropriate manner in most cases but there are places where someone decided to just execute sql. I don't like that they did this but at this point "it is what it is".

I found an explanation that seems to explain it but all the examples are wrt actually getting and managing the transaction in the code. We are using the @TransactionAttribute annotation on the entire class to change this code and are finding a lot of places where this behavior happens but I'm not entirely convinced the explanation applies to code that is simply wrapped in the annotation--I was assuming that anything using the hibernate manager would rely on the object cache in the session.

Apologies in advance if I am referring to concepts in hibernate by incorrect terminology, etc.

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

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

发布评论

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

评论(2

居里长安 2024-10-15 15:23:20

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

正如partenon指出的,仅仅基于SQL查询字符串本身,Hibernate无法知道查询中查询了哪些表和/或实体。因此,它不知道会话中排队的哪些更改需要刷新到数据库。 Chris 在博客中指出,您可以在运行 SQL 查询之前自行执行 flash() 调用。然而,我描述的是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 可以自动刷新映射到该用户表的实体的所有待处理更改。

Actually the "explanation" blog by Chris Landry misses 3 important API methods of SQLQuery and thats in fact why he has those problems. Specifically, (1) addSynchronizedQuerySpace, (2) addSynchronizedEntityName and (3) addSynchronizedEntityClass

As partenon points out, just based on the SQL query string itself Hibernate has no way to know what tables and/or entities are queried in the query. Therefore, it has no idea what changes queued up in the Session need to be flushed to the database. In the blog Chris does point out that you can perform a flush() call on your own prior to running the SQL query. However, what I am describing is Hibernate's auto-flush capability. It actually does the same thing for HQL and Criteria queries. Only there it knows the tables being affected. Anyway, this process of auto-flushing does a "minimal flush" flushing only things that affect the query. Thats where these methods come into play.

As an example, Chirs's SQL query is

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

Really all he needed to do was to say...

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

The addSynchronizedQuerySpace( "user" ) is telling Hibernate that the query uses a table named "user". Now Hibernate can auto flush all changes pending for entities mapped to that user table.

默嘫て 2024-10-15 15:23:20

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

SQL 查询或本机查询是 Hibernate 仅中继到数据库的查询。 Hibernate 不会解析查询,也不会解析结果。不过,Hibernate 会让您处理结果,将列转换为类的属性。也就是说,本机查询绕过会话缓存听起来很自然。这是因为 Hibernate 对您的查询一无所知,也不了解此查询的“结果”(此时它们不是对象)。

Your question is confusing, but I assume you are saying that Hibernate is not looking for entities in the Session cache when you are performing Native queries.

SQL Query, or Native Query, is a query which Hibernate just relays to the database. Hibernate won't parse the query, and it won't parse the results. Hibernate will, though, let you handle the results, to convert the columns into properties of a class. That said, it sounds quite natural that Native Queries would bypass the Session cache. That's because Hibernate doesn't knows anything about your query, nor about the "results" of this query (which are not objects at that point).

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