如何使用 Spring 清除所有 Hibernate 缓存(ehcache)?
Posted
技术标签:
【中文标题】如何使用 Spring 清除所有 Hibernate 缓存(ehcache)?【英文标题】:How to clear all Hibernate cache (ehcache) using Spring? 【发布时间】:2010-03-17 09:31:12 【问题描述】:我正在使用二级缓存和查询缓存。 我可以知道如何以编程方式清除所有缓存吗?
【问题讨论】:
【参考方案1】:Bozho 答案中指示的代码 sn-p 在 Hibernate 4 中已弃用。
根据Hibernate JavaDoc,可以使用org.hibernate.Cache.evictAllRegions()
:
从所有查询区域驱逐数据。
使用 API:
Session session = sessionFactory.getCurrentSession();
if (session != null)
session.clear(); // internal cache clear
Cache cache = sessionFactory.getCache();
if (cache != null)
cache.evictAllRegions(); // Evict data from all query regions.
或者,您可以清除特定范围内的所有数据:
org.hibernate.Cache.evictCollectionRegions()
org.hibernate.Cache.evictDefaultQueryRegion()
org.hibernate.Cache.evictEntityRegions()
org.hibernate.Cache.evictQueryRegions()
org.hibernate.Cache.evictNaturalIdRegions()
您可能想查看the JavaDoc for hibernate Cache interface (Hibernate 4.3)。
另外,second-level cache eviction 来自休眠开发指南 (4.3)。
【讨论】:
我想通过调用以下方法从二级缓存中清除缓存数据:- sessionFactory.getCache().evictEntityRegions();我只想知道,这样做有什么坏处吗?例如:- 如果我尝试在事务中间清除缓存会发生什么? 我想这取决于您的缓存策略和提供者。您可能需要使用所选的进行测试。参考文档描述了不同的设置。 我正在使用@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)。我有一个案例。假设某个事务正在运行以从中获取数据,并且当时二级缓存有数据。同时,另一个线程在前一个事务尚未完成时驱逐所有区域缓存。那么在这种情况下会发生什么。我可以从该事务中的缓存中获取 null 并且会发生数据库命中吗?有没有可能出现问题? 您应该根据您的特定上下文编写测试。根据文档,读写似乎与您的情况相匹配,但请注意它有要求,所有详细信息都在此处(参见docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/…)【参考方案2】:要清除会话缓存,请使用session.clear()
要清除二级缓存,请使用this code snippet
【讨论】:
对于现代版本的 Hibernate,最好遵循@dino 的回答。【参考方案3】:如果您插入 Terracotta,您还可以运行 Terracotta 开发控制台,该控制台可以检查有关缓存的统计信息、打开和关闭缓存以及从用户界面清除缓存内容。
JMX bean 也提供此功能。
【讨论】:
【参考方案4】:@Dino 的回答几乎对我有用,但我收到了来自sessionFactory.getCurrentSession()
的错误(未配置 currentSessionContext!)。我发现这对我有用:
// Use @Autowired EntityManager em
em.getEntityManagerFactory().getCache().evictAll();
// All of the following require org.hibernate imports
Session session = em.unwrap(Session.class);
if (session != null)
session.clear(); // internal cache clear
SessionFactory sessionFactory = em.getEntityManagerFactory().unwrap(SessionFactory.class);
Cache cache = sessionFactory.getCache();
if (cache != null)
cache.evictAllRegions(); // Evict data from all query regions.
【讨论】:
【参考方案5】:如果要清除二级缓存,请使用apisessionFactory.evictEntity(entityName)
代码:
/**
* Evicts all second level cache hibernate entites. This is generally only
* needed when an external application modifies the database.
*/
public void evict2ndLevelCache()
try
Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata();
for (String entityName : classesMetadata.keySet())
logger.info("Evicting Entity from 2nd level cache: " + entityName);
sessionFactory.evictEntity(entityName);
catch (Exception e)
logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e);
更多二级缓存详情refer
【讨论】:
【参考方案6】:与@Dino 的回答相同,JPA 2.0 API 的缩短语法:
@Autowired
private EntityManagerFactory entityManagerFactory;
public void clearHibernateCaches()
entityManagerFactory.getCache().unwrap(org.hibernate.Cache.class).evictAllRegions();
【讨论】:
【参考方案7】:这个也可以
request.getSession().invalidate();
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
【讨论】:
HttpSession 和休眠会话是不同的东西。以上是关于如何使用 Spring 清除所有 Hibernate 缓存(ehcache)?的主要内容,如果未能解决你的问题,请参考以下文章
grails 3(spring-boot) - 如何配置hibernate二级缓存