Что такое кэш третьего уровня (L3) в контексте Hibernate?

Ответ

В терминологии Hibernate не существует понятия "кэш третьего уровня" (L3 cache). Это распространённая путаница, возникающая из-за аналогии с архитектурой процессоров (L1/L2/L3).

Корректная терминология Hibernate:

  1. Кэш первого уровня (L1) / Кэш сессии: Привязан к объекту Session. Включён всегда, жизненный цикл равен сессии.
  2. Кэш второго уровня (L2): Общий кэш на уровне SessionFactory, как описано в предыдущем ответе.
  3. Кэш запросов (Query Cache): Отдельный кэш для результатов нативных и HQL-запросов. Часто ошибочно называют "L3". Он хранит не сущности, а идентификаторы и значения скалярных типов.

Пример настройки и использования кэша запросов:

// 1. Включение в конфигурации
// hibernate.cfg.xml: <property name="hibernate.cache.use_query_cache">true</property>

// 2. Указание кэшируемости в запросе
Session session = sessionFactory.openSession();
Query<Product> query = session.createQuery("from Product p where p.category = :cat", Product.class)
        .setParameter("cat", "Electronics")
        .setCacheable(true) // Ключевой момент!
        .setCacheRegion("product.queries"); // Опционально: регион кэша
List<Product> products = query.getResultList(); // Результат кэшируется
session.close();

// При повторном выполнении того же запроса с теми же параметрами
// Hibernate возьмёт список ID из кэша запросов и загрузит сущности из L2/L1 кэша.

Почему кэш запросов используют осторожно:

  • Он становится неактуальным при любом изменении таблиц, связанных с сущностями в запросе.
  • Эффективен только для часто выполняемых и редко меняющихся запросов с фиксированными параметрами.

Ответ 18+ 🔞

Давай раз и навсегда разберёмся с этим вопросом, а то народ путается, как в тёмном лесу, блядь.

Слушай сюда, главное запомни: в Хибернейте нет никакого "кэша третьего уровня" (L3 cache), ёпта! Всё, точка. Это выдумка, миф, пиздёж собачий, который пошёл от каких-то умников, которые решили провести аналогию с процессорами (L1, L2, L3). Вот так вот, на хуй, взяли и запутали всех.

Как на самом деле, блядь:

  1. Кэш первого уровня (L1) / Кэш сессии. Это твой личный, персональный кэш, привязанный к конкретной сессии (Session). Он всегда включён, живёт ровно столько, сколько живёт сессия, и потом накрывается медным тазом. Как будто у тебя в кармане лежит записка — пока ты её не выкинул, она твоя.

  2. Кэш второго уровня (L2). Вот это уже серьёзно, блядь. Это общий кэш на всю фабрику сессий (SessionFactory). Как общий холодильник на всю коммуналку — все туда могут заглянуть. Про него мы уже говорили.

  3. Кэш запросов (Query Cache). А вот это, сука, и есть тот самый "фантомный L3", о котором все трубят! Его так ошибочно называют. На самом деле он отдельный и хранит не сами сущности, а результаты запросов: списки идентификаторов и всякие скалярные значения. Представь, что ты записал, в каких магазинах был, но не записал, что именно купил.

Вот как этим пользоваться, на живом примере:

// 1. Сначала говоришь Хибернейту: "Хочу кэш запросов, сука!"
// В конфиге: <property name="hibernate.cache.use_query_cache">true</property>

// 2. Потом в коде, когда делаешь запрос, ты ему прямо указываешь:
Session session = sessionFactory.openSession();
Query<Product> query = session.createQuery("from Product p where p.category = :cat", Product.class)
        .setParameter("cat", "Electronics")
        .setCacheable(true) // Вот это, блядь, самый важный момент! Говоришь: "Кэшируй это!"
        .setCacheRegion("product.queries"); // Можно ещё указать "полку", куда положить (опционально)
List<Product> products = query.getResultList(); // Первый раз выполнится и закэшируется
session.close();

// А теперь, охуеть, второй раз!
// Хибернейт не полезет в базу, а достанет из кэша запросов список IDшников,
// а сами сущности подтянет уже из L2 или L1 кэша, если они там есть.

Но, чувак, с этим кэшом запросов надо как с огнём, блядь! Осторожно!

Почему? Да потому что он ебаный максималист. Любое, малейшее изменение данных в таблицах, которые участвовали в запросе — и всё, пиздец, кэш устарел, надо инвалидировать. Он эффективен только для запросов, которые:

  • Выполняются чаще, чем ты моргаешь.
  • А данные в них меняются реже, чем президент в Северной Корее.
  • И параметры запроса всегда одни и те же, как заезженная пластинка.

В общем, инструмент мощный, но если использовать его бездумно — можно получить овердохуища проблем с актуальностью данных. Думай головой, а не просто втыкай аннотации куда попало!