DEV Community

Cover image for Hibernate-кэши: как медведи хранят запасы на зиму
Olga Lugacheva
Olga Lugacheva

Posted on

Hibernate-кэши: как медведи хранят запасы на зиму

🐻 Медведи — известные мастера организации запасов. Они прячут мёд и ягоды в разных местах, чтобы зимой не остаться голодными. Но что, если в пещере места недостаточно, а запасы устаревают? Точно так же работает кэширование в Hibernate. Медведи пользуются разными уровнями кэша, чтобы ускорить "доступ к еде" (данным), но иногда из-за устаревших запасов возникают конфликты.

1. Первый уровень кэша (Session)

🐾 Медведь организовал корзинку (Session), куда кладёт ягоды сразу, как только находит их в лесу. Если он вдруг хочет перекусить, то сначала смотрит в корзину — там ли уже есть ягода? Если нет, идёт снова в лес (запрос в базу данных).
Ключевые моменты:
Hibernate автоматически кэширует объекты в пределах сессии.
Этот кэш активен только для одного медведя (одной транзакции).
Он не делится с другими медведями.

🛠 Пример:

Session session = sessionFactory.openSession();
Product product = session.get(Product.class, 1); // Запрашиваем из корзины (кэша)
session.close(); // Корзина исчезает

Enter fullscreen mode Exit fullscreen mode

Кроме get(), Hibernate может использовать load(), который создаст прокси объекта и выполнит запрос только при первом обращении к полям.

2. Второй уровень кэша (SessionFactory)

🐻 Медведи решили организовать общий склад, чтобы экономить усилия. Теперь, если мёд уже лежит на складе, они берут его оттуда, не ходя в лес.

sf
Ключевые моменты:
Кэш на уровне SessionFactory — это как общий склад, доступный всем медведям (глобальный кэш для всех сессий).
Этот кэш доступен для всех медведей (всех транзакций).
Требует настройки внешних инструментов (EHCache, Infinispan).
Но! Если ягоды испортились, а никто не проверил, это может привести к проблемам (устаревшие данные).

🛠 Пример:

<hibernate-configuration>
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
</hibernate-configuration>

Enter fullscreen mode Exit fullscreen mode

Кейс 1:

// Медведь 1
Session session1 = sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Product product1 = session1.get(Product.class, 1);
product1.setName("Fresh Honey");
session1.update(product1);
tx1.commit();
session1.close();

// Медведь 2
Session session2 = sessionFactory.openSession();
Product product2 = session2.get(Product.class, 1); // Увидит старые данные!
System.out.println(product2.getName()); // Старое значение
session2.close();
Enter fullscreen mode Exit fullscreen mode

Решение:

Используйте механизм инвалидации на уровне SessionFactory , чтобы изменения стали доступны .

sessionFactory.getCache().evict(Product.class, 1); // Удаляем старую версию объекта
Enter fullscreen mode Exit fullscreen mode

Кейс 2: медведи хранят слишком много мёда, из-за чего склад переполняется и возникает проблема нехватки памяти.

Решение: настройте стратегию очистки (eviction) в зависимости от потребностей. Используйте внешние кэш-менеджеры, например EHCache, Infinispan, или Redis.

Пример настройки EHCache:

<cache name="com.example.Product" 
       maxEntriesLocalHeap="1000" 
       timeToLiveSeconds="3600" />

Enter fullscreen mode Exit fullscreen mode

cl
Кейс3: медведи работают в кластере (распределённая архитектура), но данные кэша устаревают из-за отсутствия синхронизации.

Решение:

Используйте распределённые кэши, такие как Infinispan или Hazelcast.
Настройте синхронизацию:

hibernate.cache.region.factory_class = org.infinispan.hibernate.cache.v60.InfinispanRegionFactory
hibernate.infinispan.statistics = true

Enter fullscreen mode Exit fullscreen mode

Кейс4: фантомные данные (добавленные записи не видны в результате кэшированного запроса). Два медведя работают с одной и той же доской задач. Один медведь завершает задачу и вычёркивает её из списка.
Второй медведь пытается выполнить задачу, которая уже вычеркнута, но видит старый список (фантомные данные).

fantome
Решение: включите обновление кэша при вставке новых данных.

sessionFactory.getCache().evictQueryRegion("ProductQuery");

Enter fullscreen mode Exit fullscreen mode

3. Запросы кэша (Query Cache)

🐻 Иногда медведи помнят не только запасы, но и "списки", где указано, сколько ягод нужно собрать с каждого куста. Этот механизм позволяет кэшировать результаты запросов.

🛠 Пример:

Query query = session.createQuery("FROM Product WHERE category = :category");
query.setCacheable(true); // Включаем кэширование для запроса
query.setParameter("category", "honey");
List<Product> products = query.list();

Enter fullscreen mode Exit fullscreen mode

query

4. Когда медведям лучше не пользоваться кэшами

🐻 Если медведи пытаются запастись всем подряд, это может привести к хаосу. Некоторые данные проще запрашивать из леса напрямую (базы данных), чем поддерживать их свежесть в кэше.

Примеры:

  • Часто меняющиеся данные.
  • Ограниченная память на складе.

Вывод

🐾 Для кратковременных запасов — корзины (Session).
🐾 Для долгосрочных — склады (Second Level Cache).
🐾 Для списка задач — записи о кустах (Query Cache).
Но они помнят, что любые запасы требуют правильного управления и проверки, иначе последствия могут быть катастрофическими.

Медведи научились использовать кэши эффективно, будь как медведи!

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (0)

Postgres on Neon - Get the Free Plan

No credit card required. The database you love, on a serverless platform designed to help you build faster.

Get Postgres on Neon