很快,我有一个实体映射到DB(Oracle)中的视图,启用了二级缓存(只读策略) - ehcache。
如果我手动更新数据库中的某些列,则不会更新缓存。
我没有找到任何方法来做到这一点。仅当通过Hibernate实体进行更新时才会这样做。
我可以以某种方式实现此功能吗?
也许Job可以监控表(或视图)?或者也许有一些方法可以通知Hibernate关于具体表中DB的变化。
感谢您将来的答案!
答案 0 :(得分:2)
根据Hibernate JavaDoc,您可以使用org.hibernate.Cache.evictAllRegions()
:
evictAllRegions()从缓存中删除所有数据。
使用Session和SessionFactory:
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.
}
1)如果你只需要更新一个实体(如果直接来自db,你只会更新某些实体)而不是整个会话,你可以使用
evictEntityRegion(Class entityClass)驱逐给定区域的所有实体数据(即
2)如果你有很多实体,可以直接从db更新,你可以使用这个方法从第二级缓存中驱逐所有实体(我们可以通过JMX或其他管理工具将此方法公开给管理员): / p>
/**
* Evicts all second level cache hibernate entites. This is generally only
* needed when an external application modifies the game databaase.
*/
public void evict2ndLevelCache() {
try {
Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata();
Cache cache = sessionFactory.getCache();
for (String entityName : classesMetadata.keySet()) {
logger.info("Evicting Entity from 2nd level cache: " + entityName);
cache.evictEntityRegion(entityName);
}
} catch (Exception e) {
logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e);
}
}
3)这里有另一个apporche描述here for postgresql+hibernate,我认为你可以为Oracle做like this
答案 1 :(得分:2)
使用debezium从数据库中更新异步缓存。您可以访问https://debezium.io/
了解更多信息本文也非常有帮助,因为它可以直接实现 https://debezium.io/blog/2018/12/05/automating-cache-invalidation-with-change-data-capture/
答案 2 :(得分:1)
如前所述,当您从后端手动更新数据库(不是通过应用程序/休眠会话)时,不会更新缓存。而且您的应用程序对此一无所知。
要告知应用有关更改的信息,您需要根据情况刷新与实体相关的整个缓存或部分缓存。这可以是两种方式之一:
1-重新启动应用程序-在这种情况下,将使用更新的数据库更改来重建缓存。
2-无需重新启动应用程序即可触发更新-无需重新启动应用程序,但您想告诉应用程序当前缓存无效,应该对其进行刷新。
您可以通过多种方式将此外部推送提供给您的应用。很少 列在下面。
在执行外部push / admin任务时,您可以根据需要调用合适的与缓存相关的方法来使缓存/刷新缓存无效。示例:Session.refresh(), Cache.evictAllRegions(), Cache.evictEntityRegion(entityName) etc
,如其他帖子中所述。
答案 3 :(得分:0)
您可以使用session.refresh()
方法重新加载当前在会话中保存的对象。
答案 4 :(得分:0)
您将在此处找到控制二级缓存的方法:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-sessioncache
答案 5 :(得分:0)
从JEE 7.0开始:
myStatelessDaoBean.getSession().evict(MyEntity.class);