强制Hibernate查询访问数据库

时间:2010-09-13 13:28:55

标签: java hibernate orm hql

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

我尝试使用像select p.property from Person p where p.id = 1这样的HQL查询,其中包含事务中加载的实体的ID。

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

有什么方法吗?

4 个答案:

答案 0 :(得分:11)

  

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

简而言之:自己追踪旧价值。

  

我尝试使用HQL查询,例如从Person p中选择p.property,其中p.id = 1,其中包含事务中加载的实体的ID。

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

  

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

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

  

有什么方法吗?

要么

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

答案 1 :(得分:7)

StatelessSession为我工作。

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

答案 2 :(得分:2)

这可能有所帮助:

  

如果要强制查询缓存   刷新其中一个地区   (忽略它找到的任何缓存结果   那里)你可以使用   的 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节)。

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

答案 3 :(得分:1)

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