简体   繁体   中英

Delete method is not affecting the database if it's @Transactional

I have this simple method to delete entries from the database. It has worked fine until I added a @Transactional annotation. In this case the finishes as usual but won't delete the object.

If I remove the @Transactional annotation or the ModelMapper it works as intended. ( http://modelmapper.org/ ). And I don't see any thrown exceptions which would explain a rollback to me

Please forgive me for ignoring some best practices in my code. I just

This is not working and won't affect the db.

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

This is working:

public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

And this is working

@Transactional
public void delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
}

I'm fine with the workaround but would like to understand the reason.

Thanks

The code you marked as "working" leads to the hipothesis that the Wagon - Train relationship is fetch="EAGER"

This "not working" and "one transaction" code:

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

first loads a wagon from repository ( Wagon wagon = wagonRepository.getOne(id) ), then mark it as removed ( wagonRepository.delete(wagon) ) see: JPA entity lifecycle . Finally the Train ( wagon.getTrain() ) reference is passed to modelmapper. Because of the hipothesis expressed at the beginning of my answer Train was loaded from database before the Wagon was removed. To remove a wagon you should try also remove it from Train wagons list.

The code you marked as "working" has a semantics where each repository operation is executed in separate transaction ( Wagon wagon = wagonRepository.getOne(id) and wagonRepository.delete(wagon) ). So when you pass the train to modelmapper the wagon is already deleted from database - but - because the wagon with train was loaded before deletion the removed wagon should also be mapped to JsonTrain (assuming that JsonTran has JsonWagon list :) ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM