junior
Что такое кэш первого уровня (L1 Cache)?
Кэш первого уровня (L1 Cache) — это Persistence Context, привязанный к Session (или EntityManager). Это обязательный кэш, который нельзя отключить.
Как работает
Пример
@Transactional
public void example() {
// Запрос к БД — объект помещается в L1 Cache
User user1 = entityManager.find(User.class, 1L); // SQL SELECT
// Повторный запрос — объект берётся из L1 Cache, без SQL
User user2 = entityManager.find(User.class, 1L); // НЕТ SQL
// Гарантия идентичности
assert user1 == user2; // true — один и тот же объект
// Изменение объекта — Dirty Checking отслеживает
user1.setName("New Name");
// При commit/flush → UPDATE users SET name = 'New Name' WHERE id = 1
}
// L1 Cache уничтожается при закрытии Session/транзакции
Свойства L1 Cache
- Привязан к Session, живёт в рамках одной транзакции
- Хранит управляемые (Persistent) сущности
- Гарантирует identity — один ID → один объект в рамках Session
- Обеспечивает Dirty Checking — автоматическое обнаружение изменений
- Write-behind — SQL-запросы откладываются до flush
Очистка L1 Cache
Пример
entityManager.clear(); // очистить весь L1 Cache
entityManager.detach(user); // убрать конкретную сущность из кэша
Важное
- L1 Cache = Persistence Context = Session — это одно и то же
- Нельзя отключить — это фундаментальная часть Hibernate
- Живёт в рамках одной транзакции (
@Transactional) - Гарантирует, что два вызова
find(User.class, 1L)вернут один и тот же Java-объект
Частые ошибки
- Загрузка слишком большого количества сущностей — все загруженные сущности хранятся в L1 Cache; 100K сущностей → OutOfMemoryError
- Не использовать
clear()при batch-обработке — при вставке миллиона записей L1 Cache переполняется - Ожидать L1 Cache между транзакциями — каждая транзакция имеет свой Persistence Context; кэш не переживает транзакцию
Как используется в 2026
- L1 Cache работает прозрачно, разработчик взаимодействует с ним косвенно
- Для batch-операций:
clear()каждые N записей — обязательный паттерн - Spring
@Transactional(readOnly = true)оптимизирует L1 Cache — отключает Dirty Checking
На собеседовании: ключевое — L1 Cache = Persistence Context = Session. Он обязателен и живёт в рамках одной транзакции. Интервьюер может спросить «что будет, если дважды вызвать find() с одинаковым ID?» — ответ: второй вызов вернёт тот же объект из кэша без SQL. Упомяните проблему OOM при batch-обработке и решение через
clear().