I am using Spring-Boot, Spring Rest Controller and Spring Data JPA. If I don't specify @Transaction then also record get's created but I will like to understand how it happens.My understanding is that Spring by default adds a transaction with default parameters but not sure where it adds is it add Service layer or at Repository.
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
@Service
public class CustomerServiceImpl implements CustomerService> {
List<Customer> findByLastName(String lastName){
//read operation
}
// What will happen if @Transaction is missing. How record get's created without the annotation
public Customer insert(Customer customer){
// insert operations
}
}
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
So when you annotate a method with @Transactional , Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.
Meaning that entities fetched within a @Transactional code are automatically saved at the end. The test of the method below should still pass, even though we're not explicitly calling save() in the 16th line.
MANDATORY PropagationWhen the propagation is MANDATORY, if there is an active transaction, then it will be used. If there isn't an active transaction, then Spring throws an exception: @Transactional(propagation = Propagation.
Spring Data JPA adds the @Transactional annotation at the Repository layer specifically in the class SimpleJpaRepository.This is the base Repository class which is extended for all Spring Data JPA repositories
e.g
/*
* (non-Javadoc)
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
*/
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Although Spring add automatically the @Transactional
annotation at DAO layer, it is not the correct place nor correct behavior. The annotation must be located at service layer, there is an answered question here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With