Как очистить весь кэш Hibernate (ehcache) с помощью Spring?

Я использую кеш второго уровня и кеш запросов. Могу ли я узнать, как программно очистить все кеши?


person cometta    schedule 17.03.2010    source источник


Ответы (7)


Чтобы очистить кеш сеанса, используйте session.clear()

Чтобы очистить кэш 2-го уровня, используйте этот фрагмент кода

person Bozho    schedule 17.03.2010
comment
Для современных версий Hibernate было бы лучше следовать ответу @dino. - person King Midas; 23.10.2014

Фрагмент кода, указанный в ответе Божо, устарел в 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()

Вы можете проверить интерфейс JavaDoc для спящего кэша (Hibernate 4.3).

А также удаление кэша второго уровня из руководства по спящему режиму (4.3).

person Dino    schedule 23.12.2013
comment
Я хочу очистить данные кеша из кеша 2-го уровня, вызвав метод ниже: — sessionFactory.getCache().evictEntityRegions(); Я просто хочу знать, есть ли какой-либо вред в этом? Например: - Что произойдет, если я попытаюсь очистить кеш в середине транзакции? - person Vikas Sharma; 16.02.2017
comment
Я думаю, это зависит от вашей стратегии кэширования и провайдера. Возможно, вам придется протестировать его с выбранным. Справочный документ описывает различные настройки. - person Dino; 17.02.2017
comment
Я использую @Cache(usage = CacheConcurrencyStrategy.READ_WRITE). У меня есть случай. Предположим, выполняется какая-то транзакция для получения данных, а кеш 2-го уровня имеет данные в это время. В то же время другой поток вытесняет все кеши региона, пока предыдущая транзакция еще не завершена. Тогда что будет в этом случае. Могу ли я получить нуль из кеша в этой транзакции, и произойдет попадание в БД? Есть ли вероятность какой-либо проблемы? - person Vikas Sharma; 17.02.2017
comment
Вы должны написать тест с вашим конкретным контекстом. Согласно документации, чтение-запись, похоже, соответствует вашему случаю, но обратите внимание, что у него есть требования, подробно описанные здесь (см. docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/) - person Dino; 17.02.2017

Если вы подключите Terracotta, у вас также будет возможность запустить Terracotta Dev Console, которая может просматривать статистику о кеше, включать и выключать кеш, а также очищать содержимое кеша из пользовательского интерфейса.

Эта функциональность также доступна в bean-компонентах JMX.

person Taylor Gautier    schedule 17.03.2010

Ответ @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.
    }
person KC Baltz    schedule 30.08.2019

То же, что и ответ @Dino, сокращенный синтаксис для API JPA 2.0:

@Autowired
private EntityManagerFactory entityManagerFactory;

public void clearHibernateCaches() {
    entityManagerFactory.getCache().unwrap(org.hibernate.Cache.class).evictAllRegions();
}
person Thanh Nguyen Van    schedule 03.06.2020

Если вы хотите очистить кеш 2-го уровня, используйте API sessionFactory.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);
    }
}

Подробнее о кэше 2-го уровня см.

person atish shimpi    schedule 26.10.2015

вы также можете пойти с этим

request.getSession().invalidate();      
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
person Raju Yadav    schedule 29.01.2015
comment
HttpSession и сеанс гибернации - разные вещи. - person Sachin Verma; 02.04.2015