我正在尝试编写一个单元测试类,它必须使用相同的查询在同一测试方法中从数据库中获取结果两次。但是,当第二次启用Hibernate缓存时,它实际上并没有访问数据库,只是从缓存中获取结果。
有人可以在persistence.xml
中解答如何禁用缓存。
我尝试通过更改属性hibernate.cache.use.query_cache = false
和hibernate.cache.use_second_level_cache = false
来停用。
但它没有用。
答案 0 :(得分:19)
有人可以回答如何在persistence.xml中禁用缓存。
默认情况下禁用二级缓存和查询缓存(除非显式缓存查询,否则不会缓存查询)。无法禁用第一级缓存。
我尝试通过更改属性(...)
来禁用
这将禁用二级缓存和查询缓存,如果启用它们。
但它没有用。
说实话,“它没有用”是对当前行为与预期行为的非常糟糕的描述。提供更多细节,(伪)代码,SQL跟踪可能会有所帮助。
话虽这么说,如果问题是关于HQL,HQL查询肯定会在后续执行时命中数据库(没有任何查询缓存)。如果需要,请激活SQL日志记录。
如果问题是关于Session#get()
或Session#load()
,那么您可以使用Session#refresh()
重新加载实体的状态,或致电Session#clear()
以完全清除会话。
答案 1 :(得分:9)
Hibernate有两级Cache,
会话缓存(第一级缓存)是默认缓存,没有机制可以禁用。
SessionFactory(二级)级缓存:我们必须在Hibernate cfg文件中配置它 设置cache_provider。
我需要从数据库加载大量数据,因为以下功能,我使用了无状态会话。
a. Stateless session does not support session cache and never interact with
second level cache.
b. Stateless session does not support automatic dirty check.
c. Stateless session does not support cascading to associated entities.
创建无状态会话的语法:
StatelessSession statelessSession = sessionFactory.openStatelessSession();
答案 2 :(得分:7)
您可以使用:
session.setCacheMode(CacheMode.IGNORE)
之后:
session.createQuery("from Table")
声明。
这将确保Hibernate不会与此查询返回的任何实体的二级缓存交互。
答案 3 :(得分:4)
使用StatelessSession:
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/batch.html
答案 4 :(得分:2)
如果您在单元测试中创建一个新的(不同的)会话,它将“不”使用旧的缓存。或者如果你先调用clear()(另一个选项),等等。
答案 5 :(得分:0)
据一位来自hibenrate团队的人说:
二级缓存没有任何内容 做第一级(会话或 持久化上下文)缓存。该 持久化上下文/会话缓存是 因各种原因强制执行。在 其实不理解这个至关重要 部分并在应用程序中忽略它 建筑是一场灾难。 这里没有快速解决方案,研究 一些文档。
来源:https://forum.hibernate.org/viewtopic.php?p = 2383408
在重试相同的查询之前,您可以使用seesion.evict(您的对象)。
答案 6 :(得分:0)
第一次查询结果后,调用session.clear然后相同的查询将命中数据库而不是1级缓存
答案 7 :(得分:0)
正如 kirill 所指出的,em.clear() 方法在某些情况下实际上可以解决问题(对我有用):
entityManager.clear();