«1. Обзор

В этом коротком руководстве мы обсудим разницу между методами save() и saveAndFlush() в Spring Data JPA.

Несмотря на то, что оба эти метода используются для сохранения сущностей в базу данных, между ними есть некоторые принципиальные отличия.

2. Пример приложения

Давайте сначала посмотрим, как использовать методы save() и saveAndFlush() на примере. В качестве первого шага давайте создадим класс сущностей:

@Entity
public class Employee {

    @Id
    private Long id;
    private String name;
    
    // constructors
    // standard getters and setters
}

Затем давайте создадим репозиторий JPA для операций CRUD над классом сущностей Employee:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

3. Метод save()

Как следует из названия, метод save() позволяет нам сохранять объект в БД. Он принадлежит интерфейсу CrudRepository, определенному Spring Data. Давайте посмотрим, как мы можем его использовать:

employeeRepository.save(new Employee(1L, "John"));

Обычно Hibernate сохраняет постоянное состояние в памяти. Процесс синхронизации этого состояния с базовой БД называется сбросом.

Когда мы используем метод save(), данные, связанные с операцией сохранения, не будут сброшены в БД до тех пор, пока не будет сделан явный вызов метода flush() или commit().

Если мы используем реализации JPA, такие как Hibernate, то эта конкретная реализация будет управлять операциями сброса и фиксации.

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

4. Метод saveAndFlush()

В отличие от save(), метод saveAndFlush() сбрасывает данные сразу во время выполнения. Этот метод принадлежит интерфейсу JpaRepository Spring Data JPA. Вот как мы его используем:

employeeRepository.saveAndFlush(new Employee(2L, "Alice"));

Обычно мы используем этот метод, когда нашей бизнес-логике необходимо прочитать сохраненные изменения на более позднем этапе той же транзакции, но до фиксации.

Например, представьте себе сценарий, в котором мы должны выполнить хранимую процедуру, которая ожидает свойство объекта, которое мы собираемся сохранить. В этом случае метод save() не будет работать, так как изменения не синхронизированы с БД и хранимая процедура не знает об изменениях. Метод saveAndFlush() идеально подходит для такого сценария.

5. Заключение

В этой быстрой статье мы сосредоточились на различии между методами Spring Data JPA save() и saveAndFlush().

В большинстве случаев мы будем использовать метод save(). Но иногда нам может понадобиться использовать метод saveAndFlush() для конкретных случаев использования.

Как обычно, краткий пример, который мы здесь обсуждали, можно найти на GitHub.