Spring JPA repository transactionality

You are right. Only CRUD methods (CrudRepository methods) are by default marked as transactional.
If you are using custom query methods you should explicitly mark it with @Transactional annotation.

@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {

    UserRegistration findByEmail(String email);

    @Transactional
    void deleteByEmail(String email);

}

You should also be aware about consequences of marking repository interface methods instead of service methods. If you are using default transaction propagation configuration (Propagation.REQUIRED) then:

The transaction configuration at the repositories will be neglected
then as the outer transaction configuration determines the actual one
used.

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

If you want more information about how it is implemented, take a look at default CrudRepository / JpaRepository implementation – SimpleJpaRepository (which you are probably using):

https://github.com/spring-projects/spring-data-jpa/blob/main/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

The interesting lines are here:

@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

and some of transactional methods here:

@Transactional
public void deleteById(ID id) {
@Transactional
public <S extends T> S save(S entity) {

Leave a Comment