В JPA/Hibernate: что сохранится в БД, если в транзакционном методе вызвать persist/save, а затем изменить состояние объекта?

«В JPA/Hibernate: что сохранится в БД, если в транзакционном методе вызвать persist/save, а затем изменить состояние объекта?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В базу данных будут сохранены все изменения, сделанные с объектом внутри транзакции, включая те, что выполнены после persist() или save(). Это происходит из-за механизма автоматической проверки изменений (dirty checking).

Пример:

@Transactional
public void saveAndUpdatePerson(Person person) {
    // 1. Делаем объект управляемым (persistent). Его состояние отслеживается.
    entityManager.persist(person); // В Hibernate: session.save(person)

    // 2. Изменяем состояние управляемого объекта.
    person.setAge(30);
    person.setName("Updated Name");

    // 3. При коммите транзакции Hibernate автоматически обнаружит изменения
    // и выполнит SQL UPDATE для полей `age` и `name`.
    // В БД будет запись с ВСЕМИ изменениями, а не только с исходным состоянием.
}

Ключевые принципы:

  • persist() (JPA) / save() (Hibernate API) переводят объект в управляемое (persistent) состояние.
  • Пока транзакция активна, Persistence Context отслеживает все изменения в управляемых объектах.
  • При завершении транзакции (@Transactional метод завершается) Hibernate синхронизирует (flush) состояние контекста с БД, выполняя необходимые INSERT и UPDATE.
  • Явный вызов flush() не обязателен, но может быть полезен для контроля или валидации.