强制 Hibernate 查询访问数据库

发布于 2024-09-19 03:30:27 字数 315 浏览 2 评论 0原文

我已将一个实体加载到我的交易中并更改了该实体的属性。该交易尚未提交。现在我想获取更改后的属性的原始值。

我尝试过使用 HQL 查询,例如 select p.property from Person p where p.id = 1 以及事务中加载的实体的 ID。

我在执行查询之前设置了 query.setHint("org.hibernate.cacheMode", CacheMode.IGNORE); 。但没有成功。 Hibernate 返回当前事务中设置的值,而不是数据库中的值。

有什么办法解决这个问题吗?

I have loaded an entity into my transaction and have changed a property of that entity. The transaction is not yet commited. Now I would like to get the original value of the changed property.

I've tried with a HQL query like select p.property from Person p where p.id = 1 with the ID of the entity loaded in the transaction.

I've set query.setHint("org.hibernate.cacheMode", CacheMode.IGNORE); before executing the query. But no success. Hibernate returns the value as set in the current transaction, not the one from the database.

Is there any way around this?

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

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

发布评论

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

评论(4

妥活 2024-09-26 03:30:27

我已将一个实体加载到我的事务中并更改了该实体的属性。该交易尚未提交。现在我想获取更改后的属性的原始值。

简而言之:自己跟踪旧值。

我尝试过使用 HQL 查询,例如 select p.property from Person p where p.id = 1 以及事务中加载的实体的 ID。

Hibernate 将给定数据库标识符的实体的唯一版本加载到会话(第一级缓存)中。这行不通。

我已经设置了 query.setHint("org.hibernate.cacheMode", CacheMode.IGNORE);在执行查询之前。

此提示用于影响查询缓存(依赖于二级缓存),这不会影响您当前的“问题”。

有什么办法可以解决这个问题吗?

使用

  • session.refresh() 强制重新加载实体(并且您将丢失更改)
  • 存储最初提到的先前值。
  • 调用在另一个事务中执行查询的服务。

I have loaded an entity into my transaction and have changed a property of that entity. The transaction is not yet commited. Now I would like to get the original value of the changed property.

In short: track the old value yourself.

I've tried with a HQL query like select p.property from Person p where p.id = 1 with the ID of the entity loaded in the transaction.

Hibernate loads a unique version of an entity into the session (the first level cache) for a given database identifier. This won't work.

I've set query.setHint("org.hibernate.cacheMode", CacheMode.IGNORE); before executing the query.

This hint is used to affect the query cache (that rely on the second-level-cache), this won't affect your current "issue".

Is there any way around this?

Either

  • use session.refresh() to force a reload of your entity (and you'll loose the changes)
  • store the previous value as initially mentioned.
  • invoke a service that perform a query in another transaction.
吾性傲以野 2024-09-26 03:30:27

StatelessSession 对我有用。

StatelessSession statelessSession = sessionFactory.openStatelessSession();
try {
    return statelessSession.get(Ticket.class, ticketKey, LockMode.READ)
} finally {
   statelessSession.close()
} 

The StatelessSession worked for me.

StatelessSession statelessSession = sessionFactory.openStatelessSession();
try {
    return statelessSession.get(Ticket.class, ticketKey, LockMode.READ)
} finally {
   statelessSession.close()
} 
千仐 2024-09-26 03:30:27

这可能有帮助:

如果你想强制查询缓存
刷新其区域之一
(忽略它找到的任何缓存结果
在那里)你可以使用
org.hibernate.Query.setCacheMode(CacheMode.REFRESH)
结合您所在的地区
已为给定查询定义,
Hibernate 会选择性地强制
结果缓存在该特定的
要刷新的区域。这是
在以下情况下特别有用
基础数据可能已更新
通过一个单独的过程,并且是一个遥远的过程
比批量更有效的替代方案
通过驱逐该地区
org.hibernate.SessionFactory.evictQueries()。

(来自http://docs.jboss.org/hibernate/stable/core/reference/en/html/performance.html,第 20.4.2 节)。

但是,它是否打算在其他进程更新数据库时使用,应谨慎使用。
你的情况有所不同。由于此方法发生在任何事务之外,因此您应该确保它不会与您的设计冲突。也许您可以重构您的调用流程以避免这种行为,并从另一个源或在缓存中的修改发生之前检索该字段......

This may help:

If you want to force the query cache
to refresh one of its regions
(disregard any cached results it finds
there) you can use
org.hibernate.Query.setCacheMode(CacheMode.REFRESH).
In conjunction with the region you
have defined for the given query,
Hibernate will selectively force the
results cached in that particular
region to be refreshed. This is
particularly useful in cases where
underlying data may have been updated
via a separate process and is a far
more efficient alternative to bulk
eviction of the region via
org.hibernate.SessionFactory.evictQueries().

(From http://docs.jboss.org/hibernate/stable/core/reference/en/html/performance.html, section 20.4.2).

However, is it intended to use when other process is updating the DB, and should be used with care.
Your case is different. As this method occurs outside any transaction, you should be sure it does not conflict with your design. Maybe you can refactor your call flow to avoid that behavior, and retrieve the field from another source or before the modification in the cache takes place...

尘世孤行 2024-09-26 03:30:27

执行此操作的唯一方法是在当前事务之外运行查询。

The only way to do this would be to run the query outside of the current transaction.

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