Hibernate Session
Здесь Session — Hibernate persistence context, а не HTTP session. Он связывает Java-объекты с записями БД, отслеживает изменения и координирует SQL в рамках единицы работы.
Жизненный цикл
try (Session session = sessionFactory.openSession()) {
Transaction tx = session.beginTransaction();
try {
Order order = session.find(Order.class, 42L);
order.markPaid();
tx.commit();
} catch (RuntimeException ex) {
tx.rollback();
throw ex;
}
}После find entity становится managed. Hibernate делает dirty checking и обычно формирует UPDATE при flush. commit вызывает flush, но flush не равен commit: SQL может уйти в БД, а транзакция затем откатиться.
Состояния entity
- transient — новый объект вне persistence context;
- managed/persistent — отслеживается текущей Session;
- detached — был managed, но Session закрыта/очищена;
- removed — помечен на удаление.
Первая identity map Session гарантирует, что повторная загрузка одной строки в этом контексте обычно возвращает тот же Java object. Это не общий application cache.
Session и transaction
Session можно технически держать дольше одной transaction, но безопасная модель сервиса — короткая единица работы и явная transaction boundary. Обычная JDBC-транзакция не становится вложенной от второго вызова beginTransaction. В Spring semantics вложенности определяет transaction manager и propagation; NESTED обычно опирается на savepoint, если он поддерживается.
Session не thread-safe. Нельзя передавать её между параллельными задачами.
Lazy loading
Lazy proxy/collection требует открытого persistence context. Если слой web трогает связь после закрытия Session, возникает LazyInitializationException. Исправление — загрузить нужную проекцию или association внутри транзакции, а не держать Session открытой без границ.
Типичные сбои
- Открыть transaction и забыть rollback при исключении.
- Путать flush с успешным commit.
- Сериализовать managed entity вместе с ленивым графом.
- Разделять Session между threads.
- Загружать тысячи managed entities и раздувать first-level cache.
- Использовать
merge, не понимая, что возвращается managed copy, а переданный object остаётся detached.
Вопросы для собеседования
Что хранит persistence context? Managed entities и их identity/снимки, необходимые для dirty checking.
Чем flush отличается от commit? Flush синхронизирует изменения с БД в текущей transaction, commit окончательно фиксирует её.
Session thread-safe? Нет.
Почему возникает LazyInitializationException? Lazy association пытаются загрузить без доступной Session.
Что произойдёт с managed entity после изменения поля? При flush Hibernate обнаружит dirty state и сформирует SQL, если изменение отображается и transaction позволяет.