我已将实体加载到我的事务中并更改了该实体的属性。该交易尚未提交。现在我想获得已更改属性的原始值。
我尝试使用像select p.property from Person p where p.id = 1
这样的HQL查询,其中包含事务中加载的实体的ID。
我在执行查询之前设置了query.setHint("org.hibernate.cacheMode", CacheMode.IGNORE);
。但没有成功。 Hibernate返回当前事务中设置的值,而不是数据库中的值。
有什么方法吗?
答案 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)
执行此操作的唯一方法是在当前事务之外运行查询。