Какие состояния объекта существуют в Hibernate и чем они отличаются?

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

Ответ

Hibernate управляет жизненным циклом сущности через 4 состояния, определяемых ее связью с Session (или EntityManager).

Состояние Связь с Session Идентификатор (ID) В БД? Синхронизация изменений
Transient (Временный) Нет Может быть null или задан Нет Не отслеживаются
Persistent (Управляемый) Да Есть (не null) Да (или будет при flush) Автоматическая при коммите транзакции
Detached (Отсоединенный) Нет (была раньше) Есть Да Не отслеживаются
Removed (На удаление) Да Есть Да (пока не удалена) Будет удалена при коммите

Примеры и переходы:

// 1. TRANSIENT: новый объект, не связан с сессией
Session session = sessionFactory.openSession();
User user = new User(); // ID = null, состояние TRANSIENT
user.setName("John");

// 2. PERSISTENT: объект ассоциирован с сессией
session.save(user); // или session.persist(user)
// Теперь user имеет сгенерированный ID, состояние PERSISTENT
user.setEmail("john@example.com"); // Изменение будет автоматически записано в БД

// 3. DETACHED: сессия закрыта, объект больше не управляется
session.close();
// Объект user теперь в состоянии DETACHED
user.setName("Jane"); // Изменение НЕ синхронизируется с БД

// Чтобы снова сделать объект управляемым, используйте merge()
Session newSession = sessionFactory.openSession();
User managedUser = newSession.merge(user); // Возвращает управляемый экземпляр

// 4. REMOVED: объект помечен на удаление в текущей сессии
newSession.delete(managedUser); // Состояние REMOVED
// Удаление из БД произойдет при session.flush() или коммите транзакции

Ключевое отличие между Persistent и Detached — в автоматической синхронизации изменений с базой данных.