Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I save without @Transactional? [duplicate]

Simplified example:

@Entity
public class Foo {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;
  private String bar;

  // getters + setters

}

public interface FooRepository extends CrudRepository<Foo, Integer> {
}

@Service
public class FooService {

  private final FooRepository repository;

  public FooService(FooRepository repository) {
    this.repository = repository;
  }

  public Foo save(Foo foo) {
    return repository.save(foo);
  }

}

Calling fooService.save(myNewFoo) from a controller works, while I would have expected it to fail (if I understand transactions correctly), as no method has been annotated with @Transactional (and I actually would like it to fail). Any idea why this behavior? Who's creating a transaction behing the scene, and how to avoid this?

Additional details:

  • Java 9
  • MySQL connector 6.0.6
  • Hibernate 5.2.12
  • Spring Boot 2.0.0.M7
  • Spring Data JPA 2.0.2.RELEASE
like image 845
sp00m Avatar asked Dec 14 '17 12:12

sp00m


People also ask

Why does @transactional save automatically to database?

Since your object is already changed within the context of the persistence context and the transaction, the changes are saved to the database even without the need to explicitly call a save method.

Is CrudRepository save transactional?

CrudRepository's "save" operation commits transaction even if Service does rollback [DATAJPA-219] #631.

What is difference between save and Saveflush?

Normally, Hibernate holds the persistable state in memory. The process of synchronizing this state to the underlying DB is called flushing. When we use the save() method, the data associated with the save operation won't be flushed to the DB unless, and until, an explicit call to the flush() or commit() method is made.

How does Jparepository save work?

The save operation performs a merge on the underlying EntityManager . This on its own doesn't perform any SQL but just returns a managed version of the entity. If that isn't already loaded into the EntityManager it might do this or it might identify the entity as a new one and make it a managed entity.


1 Answers

The implementation of CrudRepository#save provided by Spring creates a transaction by default. Please see the documentation for further details.

like image 156
Sync Avatar answered Oct 23 '22 14:10

Sync