11

By Default, Spring Data JPA has auto-commit disabled.
So if I am using/extending CrudRepository to save an object using save method, what is happening behind the scene?? After saving the object to DB does spring jpa also commit the operation or not.
If it does not, how can i explicitly commit the operation?

Edit following "Michal Drozd" comment: (The below is for JpaRepository not CrudRepository)
This article: Difference Between save() and saveAndFlush() in Spring Data JPA seems to indicate that for Spring Data JPA, auto-commit is false by default.

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.

  • @MichalDrozd could you further bolster your case with any reference. I will greatly appreciate it as I can use the same reference to present to my peers. –  Oct 01 '20 at 09:15
  • @joveny It's the other way round. Hibernate is built on top of JPA. JPA(Java Persistence API) is a specification while its popular implementations are Hibernate, EclipseLink,etc. – Ayush28 Oct 01 '20 at 10:01
  • 2
    @Ayush28, I meant Spring Data JPA, not JPA as in the comment. ( I re-posted the comment). Thanks for pointing. So what I meant is Spring Data JPA is built on top of Hibernate while Hibernate is an implementation of JPA. –  Oct 01 '20 at 10:04
  • @MichalDrozd, thanks. I googled for JDBC auto-commit mode and found this `When a connection is created, it is in auto-commit mode.` Ref -> [Using Transactions](https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html). Similarly for Hibernate i found this : `By default the autocommit value is false, therefore the transaction needs to be commited explicitly.` Ref -> [SOF](https://stackoverflow.com/questions/23100888/why-is-hibernate-connection-autocommit-true-not-recommended-in-hibernate). Since, Spring Data JPA is built on top of Hibernate, I thought it too has autocommit false. –  Oct 01 '20 at 10:07
  • 1
    to be more precise - Spring Data JPA is built on top of JPA Provider - be it Hibernate or something else... hope so –  Oct 01 '20 at 10:15
  • @joveny actually you are right, autocommit in JPA is default off, my fault, so if your database has autocommit OFF then you have to turn autocommit to ON in your JPA. Just add `spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true` to your application.properties if you are using spring boot and you will see all raw SQL statements – Michal Drozd Oct 01 '20 at 10:22
  • @MichalDrozd, thanks for reverting. The main Q is about how to commit explicitly. For `CrudRepository` there is no `commit` method. And even for the `JpaRepository` there is only `saveAndFlush` method there is no `saveAndCommit` or `commit` method. –  Oct 01 '20 at 10:26
  • @MichalDrozd Using `@Transnational` or using programmatic transaction management probably it can be achieved - but seems to be a over kill. –  Oct 01 '20 at 10:27

2 Answers2

2

If Spring JPA autocommit is turned on (spring.datasource.hikari.auto-commit=true), then during database setup (during spring initilization) autocommit variable is set in database to true (for MySQL it is SET autocommit=1), it will not call commit for each SQL statement. If you want to use commit then you need transaction. So either enable autocommit or work in transactions.

Michal Drozd
  • 1,311
  • 5
  • 13
  • 26
2

save() method of CrudRepository is @Transactional itself. So if you call it not in context of another transaction it will create one and commit or rollback it depending on success or failure of persisting entity.

  • 1
    any reference to bolster your answer? –  Oct 01 '20 at 16:25
  • 3
    I should have worded it a little bit differently. `CrudRepository` is just an interface so its methods are not transactional. But Spring Data Jpa implementation of `CrudRepository` is `SimpleJpaRepository` and it has @Transactional annotation on a number of methods including `save()` – Strokov Sergey Oct 01 '20 at 16:32