Hibernate 2nd level cache invalidation when another process modifies the database

前端 未结 6 1111
[愿得一人]
[愿得一人] 2020-12-07 19:16

We have an application that uses Hibernate\'s 2nd level caching to avoid database hits.

I was wondering if there is some easy way to invalidate the Java application

相关标签:
6条回答
  • 2020-12-07 19:37

    Both hibernate and JPA now provide direct access to the underlying 2nd level cache:

    sessionFactory.getCache().evict(..);
    entityManager.getCache().evict(..)
    
    0 讨论(0)
  • 2020-12-07 19:41

    I was searching how to invalidate all Hibernate caches and I found this useful snippet:

    sessionFactory.getCache().evictQueryRegions();
    sessionFactory.getCache().evictDefaultQueryRegion();
    sessionFactory.getCache().evictCollectionRegions();
    sessionFactory.getCache().evictEntityRegions();
    

    Hope it helps to someone else.

    0 讨论(0)
  • 2020-12-07 19:42

    You may try doing this:

    private EntityManager em;
    
    public void clear2ndLevelHibernateCache() {
        Session s = (Session) em.getDelegate();
        SessionFactory sf = s.getSessionFactory();
    
        sf.getCache().evictQueryRegions();
        sf.getCache().evictDefaultQueryRegion();
        sf.getCache().evictCollectionRegions();
        sf.getCache().evictEntityRegions();
    
        return;
    }
    

    I hope It helps.

    0 讨论(0)
  • 2020-12-07 19:50

    SessionFactory has plenty of evict() methods precisely for that purpose:

    sessionFactory.evict(MyEntity.class); // remove all MyEntity instances
    sessionFactory.evict(MyEntity.class, new Long(1)); // remove a particular MyEntity instances
    
    0 讨论(0)
  • 2020-12-07 19:54

    One thing to take into account when using distributed cache is that QueryCache is local, and evicting it on one node, does not evicts it from other. Another issue is - evicting Entity region without evicting Query region will cause N+1 selects,when trying to retrieve date from Query cache. Good readings on this topic here.

    0 讨论(0)
  • 2020-12-07 19:56

    Based on ChssPly76's comments here's a method that evicts all entities from 2nd level cache (we can expose this method to admins through JMX or other admin tools):

    /**
     * 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();
            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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题