13

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
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • 4
    By default the methods of `CrudRepository` and friends are `@Transactional`. – M. Deinum Dec 14 '17 at 12:13
  • @M.Deinum Any way to make them not `@Transactional` then? Apart from rewriting the whole implementation myself? I would like my services to be in charge of transactions, and fail otherwise. – sp00m Dec 14 '17 at 12:15
  • @M.Deinum Maybe can I extend `SimpleJpaRepository` and disable the `@Transaction`s in some way? – sp00m Dec 14 '17 at 12:20
  • 1
    How about reading the release notes... https://jira.spring.io/browse/DATAJPA-685 – M. Deinum Dec 14 '17 at 12:24
  • @M.Deinum Sounds like a good idea. – sp00m Dec 14 '17 at 12:29

1 Answers1

14

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

Sync
  • 3,571
  • 23
  • 30