Какую роль играет кэширование в ORM (на примере Hibernate) и какие уровни кэша существуют?

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

Ответ

Кэширование в ORM минимизирует обращения к базе данных, сохраняя загруженные сущности и результаты запросов в памяти.

Основные преимущества:

  • Резкое повышение производительности для операций чтения, особенно при повторных обращениях к одним и тем же данным.
  • Снижение нагрузки на СУБД за счет сокращения количества выполняемых SQL-запросов.
  • Обеспечение консистентности в рамках сессии (кэш первого уровня).

Уровни кэширования в Hibernate:

Уровень Область видимости Назначение
Кэш 1-го уровня (L1) Сессия (Session) Автоматический. Гарантирует, что в рамках одной сессии загрузка сущности по идентификатору всегда возвращает один и тот же экземпляр объекта.
Кэш 2-го уровня (L2) Фабрика сессий (SessionFactory) Опциональный, общий для всех сессий. Требует явного включения и провайдера (Ehcache, Infinispan, Redis).
Кэш запросов Фабрика сессий (SessionFactory) Кэширует результаты часто выполняемых HQL/JPA-запросов или критериев. Работает только при включенном L2-кэше.

Пример настройки L2-кэша для сущности:

@Entity
@Cacheable // Активация кэширования для JPA
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // Стратегия Hibernate
public class Product {
    @Id
    private Long id;
    private String name;
}

Важные аспекты:

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