JpaRepository save vs saveAndFlush method

JpaRepository save vs saveAndFlush methods

  • 1.  JpaRepository.save() Method :
    • The save() method in Spring Data JPA is used to persist an entity to the database.
    • When you call save(entity), Spring Data JPA manages the entity’s persistence context until the transaction is committed or flushed.
    • This method does not immediately trigger an SQL INSERT operation in the database; instead, it schedules the entity to be persisted during the transaction commit or flush.
  • 2.  JpaRepository.saveAndFlush() Method :
    • The saveAndFlush() method, on the other hand, not only saves the entity to the database but also immediately flushes the changes to the database.
    • Flushing means that the underlying JPA provider (like Hibernate) will execute an SQL INSERT, UPDATE, or DELETE statement to synchronize the state of entities with the database.
    • This method is useful when you need to ensure that changes are persisted immediately, rather than waiting until the end of the transaction.

JpaRepository save vs saveAndFlush method

Example in Java

Here’s a Java example illustrating the use of save() and saveAndFlush() methods in a Spring Data JPA repository:

Entity Class (User.java)
java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String email;

    // Constructors, getters, and setters
}

Spring Data JPA Repository Interface (UserRepository.java)
java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Service or Controller Example Using save() and saveAndFlush()
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void saveUser(User user) {
        // Using save() method
        userRepository.save(user); // Persists the user entity within the transaction context
        // Other operations within the transaction

        // Using saveAndFlush() method
        userRepository.saveAndFlush(user); // Persists the user entity and immediately flushes changes to the database
        // After saveAndFlush(), changes are visible to subsequent database operations
    }
}

Explanation of the Example

  • save() Method : The userRepository.save(user) method schedules the user entity to be persisted within the current transaction. The actual SQL INSERT operation occurs when the transaction commits.
  • saveAndFlush() Method : The userRepository.saveAndFlush(user) method persists the user entity and immediately executes an SQL INSERT statement to persist changes to the database. This ensures that changes are visible to subsequent database operations within the same transaction.
  • Transactional Context : Both save() and saveAndFlush() methods are typically used within a transactional context (@Transactional), ensuring that changes to entities are consistent and atomic.