Настраивали ли вы кэширование в Hibernate?

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

Ответ

Да. Hibernate предоставляет трехуровневую систему кэширования.

1. Кэш первого уровня (L1 Cache, Session Cache)

  • Включен по умолчанию, привязан к объекту Session.
  • Жизненный цикл — длительность сессии. Пример:
    Session session = sessionFactory.openSession();
    User u1 = session.get(User.class, 1L); // Запрос к БД
    User u2 = session.get(User.class, 1L); // Данные берутся из L1 кэша
    session.close(); // Кэш очищается

2. Кэш второго уровня (L2 Cache)

  • Разделяемый кэш между сессиями. Требует явной настройки провайдера (Ehcache, Infinispan).
  • Конфигурация в persistence.xml:
    <property name="hibernate.cache.use_second_level_cache" value="true"/>
    <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
  • Аннотирование сущности:
    @Entity
    @Cacheable
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public class Product { ... }

3. Кэш запросов (Query Cache)

  • Кэширует результаты или идентификаторы объектов для конкретного HQL/SQL-запроса с параметрами.
  • Включение:
    <property name="hibernate.cache.use_query_cache" value="true"/>
  • Использование в коде:
    Query query = session.createQuery("from User where active = true");
    query.setCacheable(true);

Важно: Кэш запросов эффективен только вместе с настроенным L2 кэшем.