I have a Spring Boot application and I face a weird issue.
I try to make one of my service method transactional but this doesn't work.
My service looks like this :
@Service("ppService")
public class PlanProgresServiceImpl implements PlanProgresService
{
@Resource
private DeploiementDAO deploiementDao;
...
@Override
@Transactional(rollbackFor = TechnicalErrorException.class)
public Set<String> deployer(PlanProgresType planProgresType, List<Integer> listIdUo, boolean sharepoint, Campagne campagne)
throws TechnicalErrorException
...
createDeploiement(deploiement);
throw new TechnicalErrorException("temporary exception to test the transactional behavior");
}
@Override
public void createDeploiement(Deploiement deploiement)
{
deploiementDao.save(deploiement);
}
}
And here is my DAO :
public interface DeploiementDAO extends CrudRepository<Deploiement, Integer>
{
List<Deploiement> findByUniteOperationnelle(UniteOperationnelle uo);
}
The thing is that my Deploiement object is always inserted in database (a PostgreSQL one).
I have added the following line in my application.yml logging.level.org.springframework.transaction.interceptor: TRACE
And it gives me this in the console :
2017-05-02 19:38:24.297 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Getting transaction for
[org.springframework.data.jpa.repository.support.SimpleJpaRepository.findOne]
2017-05-02 19:38:24.310 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findOne]
2017-05-02 19:38:24.312 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findOne]
2017-05-02 19:38:24.323 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findOne]
2017-05-02 19:38:24.324 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Don't need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByUniteOperationnelle]: This method isn't transactional.
2017-05-02 19:38:24.449 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2017-05-02 19:38:24.450 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
Which means that every methods of SimpleJpaRepository are transactional, that is true when we look at its code :
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
So, how can I solve this ?
Closing this issue. I was a junior back then and I had a bad understanding of how @Transactional
worked with Spring.
TechnicalErrorException
needed to be a RuntimeException
instead of CheckedException
.
Here is a link that talks about the Transactional Pitfalls: https://codete.com/blog/5-common-spring-transactional-pitfalls