ChatGPT解决这个技术问题 Extra ChatGPT

Difference between save and saveAndFlush in Spring data jpa

I am trying to learn spring data JPA by testing some CRUD operation via JpaRepository.

I came across two methods save and saveAndFlush. I don't get the difference between these two. On calling save also my changes are getting saved into database so what is the use of saveAndFlush.


H
Hearen

On saveAndFlush, changes will be flushed to DB immediately in this command. With save, this is not necessarily true, and might stay just in memory, until flush or commit commands are issued.

But be aware, that even if you flush the changes in transaction and do not commit them, the changes still won't be visible to the outside transactions until the commit in this transaction.

In your case, you probably use some sort of transactions mechanism, which issues commit command for you if everything works out fine.


"won't be visible to the outside transactions until the commit in this transaction" It depends on the isolation level of the other transactions. If a transaction's isolation level is READ_UNCOMMITTED,then it will see what has been flushed but not yet committed by other transactions.
but, in my project, I use save(), saveAll() & it persists in DB without commit or flush calling explicitly. Then why should I prefer saveAndFlush? FLush mode all those things are in default mode
P Satish Patro, saveAndFlush() is used for immediate flush. If you use save(), the flush action will be handled by JPA later.
H
Hearen

Depending on the hibernate flush mode that you are using (AUTO is the default) save may or may not write your changes to the DB straight away. When you call saveAndFlush you are enforcing the synchronization of your model state with the DB.

If you use flush mode AUTO and you are using your application to first save and then select the data again, you will not see a difference in bahvior between save() and saveAndFlush() because the select triggers a flush first. See the documention.


sorry but if I save an entity and again the same one, you mean with save the second command won't throw an exception for duplication for example??
@Bludream Yes, it is my understanding that calls to save are idempotent. See this thread for more details.
D
Dinushika Rathnayake

Both methods are used to save entities to the database. Flushing is the process of synchronizing the state of the persistence context with the underlying database.

When using saveAndFlush method, data immediately flush to the database and to do it with the save method we need to call flush() method explicitly. Using flush can read saved changes at a later step during the same transaction but before the commit. So still can rollback if no need to commit.


G
Geeth

In Spring Data Jpa save() method allows us to save an entity to the DB. It belongs to the CrudRepository interface defined by Spring Data.

When we use the save() method, the data associated with the save operation will not be flushed to the DB unless and until an explicit call to flush() or commit() method is made.

As an example, let's create an Entity and JPA repository.

@Data
@Entity
public class User{

    @Id
    private Long id;
    private String name;
}


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

Then can be used save() method like this,

userRepository.save(new User(1L, "Geeth"));

But saveAndFlush() method unlike save(). The saveAndFlush() method flushes the data immediately during the execution. This method belongs to the JpaRepository interface of Spring Data JPA. you can use it as follows.

userRepository.saveAndFlush(new User(2L, "Sam"));

Normally, we use this method when our business logic needs to read the saved changes at a later point during the same transaction but before the commit.

For instance, imagine a scenario where we have to execute a stored procedure that expects a property of the entity, which we're going to save. In this case, the save() method won't work since the changes are not in sync with the DB and the stored procedure doesn't know about the changes. The saveAndFlush() method is perfectly suited for this kind of scenario.