Что такое кэш второго уровня (L2 cache) в Hibernate?

«Что такое кэш второго уровня (L2 cache) в Hibernate?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Кэш второго уровня (L2 cache) в Hibernate — это кэш сессий (SessionFactory), общий для всех сессий (Session), созданных из одной фабрики. Он хранит загруженные сущности и коллекции, что позволяет избежать повторных запросов к БД в разных транзакциях.

Отличие от кэша первого уровня (L1):

  • L1 cache привязан к конкретной сессии (Session) и живет только во время её существования.
  • L2 cache разделяется между всеми сессиями приложения.

Конфигурация и использование:

  1. Выбор провайдера кэша: Ehcache, Infinispan, Hazelcast, Caffeine.
  2. Включение в persistence.xml или hibernate.cfg.xml:
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
  3. Аннотирование сущностей:
    @Entity
    @Cacheable // Включает сущность в L2 cache
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // Стратегия
    public class Product { ... }

Стратегии согласованности (CacheConcurrencyStrategy):

  • READ_ONLY: для неизменяемых данных.
  • READ_WRITE: использует мягкие блокировки, обеспечивает согласованность для часто читаемых, но редко изменяемых данных.
  • NONSTRICT_READ_WRITE: обновления кэша после коммита транзакции, возможны краткие периоды несогласованности.
  • TRANSACTIONAL: полная поддержка транзакций (JTA), самая строгая.

Важные моменты:

  • Кэшируются только идентифицируемые сущности (с @Id). Запросы (Query) кэшируются отдельно (query cache).
  • При изменении данных через нативные SQL или другие приложения кэш может устареть — требуется инвалидация или использование стратегий с учетом этого.