如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个? [英] How to force @Transactional in JPA to commit two repository action not only just the last one?

查看:355
本文介绍了如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现的目标是对数据库进行更新".然后执行删除"操作带有Spring Data JPA和@Transactional批注的操作,我希望两个操作都执行,但是如果其中一个操作失败,则需要回滚,我该如何正确执行此操作?

Hi what i trying to achieve is to do "UPDATE" action and then do "DELETE" action with Spring Data JPA and @Transactional annotation, and i want both action is executed but if one of the action is failed, i need a rollback, how do i do this properly?

首先是我的服务班级:

@Transactional
@Service
public class TransDeliveryPlanningService {

    public ResponseRequest<TransDeliveryPlanning> deleteTransDeliveryPlanning(InputDeleteRequest<ViewAndDeleteRequest> request) {
        String currentUser = request.getLoggedInUser();
        String reasonDeleted = request.getReason();
        Long id = request.getObject().getId();
        ResponseRequest<TransDeliveryPlanning> response = new ResponseRequest<TransDeliveryPlanning>();

        TransDeliveryPlanning transDeliveryPlanningOld = transDeliveryPlanningRepository.findById(id).orElseThrow(() -> new ResourceNotFound("Data "+ id +" not found!"));
        transDeliveryPlanningOld.setIsDeleted(true);
        transDeliveryPlanningOld.setReasonDeleted(reasonDeleted);
        transDeliveryPlanningOld.setModifiedBy(currentUser);
        
        TransDeliveryPlanning updatedTransDeliveryPlanning = transDeliveryPlanningRepository.save(transDeliveryPlanningOld);

        transDeliveryPlanningRepository.delete(transDeliveryPlanningOld);

        //NOTE delete transStuffing
        List<TransStuffing> transStuffing = transStuffingRepository.findBydeliveryPlanningId(transDeliveryPlanningOld.getId());
        Boolean deletePermit = false;
        for(TransStuffing ts : transStuffing) {
            if(ts.getStatus().equalsIgnoreCase("new")) {
                deletePermit = true;
            } else {
                throw new ResourceIsDelete("Stuffing " + ts.getStuffingNo() + " Status already changed, delete is not permited!");
            }
        }

        if(deletePermit){
            transStuffingRepository.deleteAll(transStuffing);
        }

        //NOTE end of delete transStuffing

        if(updatedTransDeliveryPlanning != null) {
            response.setResponse("Sukses Hapus");
            response.setObject(updatedTransDeliveryPlanning);
        } else {
            response.setResponse("Gagal Hapus");
        }
        
        return response;
    }

}

如您所见,我执行 transDeliveryPlanningRepository.save ,然后下一行执行 transDeliveryPlanningRepository.delete ,我需要执行的下一个仓库是 transStuffingRepository.deleteAll

as you can see, i do transDeliveryPlanningRepository.save and then the next line i do transDeliveryPlanningRepository.delete and the next repo i need to execute is transStuffingRepository.deleteAll

我需要在删除之前保存的目标是使用Hibernate Audit Envers创建AuditLog,因此我想将删除原因记录到我的审核表中,然后删除记录.但是,当我使用**@Transactional**注释但未执行 transDeliveryPlanningRepository.save (更新)时,我的函数只是执行 transDeliveryPlanningRepository.delete transStuffingRepository.deleteAll 如何使用@Transactional批注保持保存?

The goal i need to do save before delete is i use Hibernate Audit Envers to create an AuditLog, so i want log the delete reason into my audit table and then delete the record. But when i use **@Transactional** annotation the transDeliveryPlanningRepository.save (update) not executed, my function just execute transDeliveryPlanningRepository.delete and transStuffingRepository.deleteAll how i keep the save executed with @Transactional annotation?

更新

正如Morteza Bandi回答以下建议一样,这是我的更新代码: 这是我的资料库:

As Morteza Bandi answer below suggestion, here is my updated code : here is my repository :

@Repository
public interface TransDeliveryPlanningRepository extends RevisionRepository<TransDeliveryPlanning, Long, Integer>, JpaRepository<TransDeliveryPlanning, Long> {
    
    @Modifying
    TransDeliveryPlanning save(TransDeliveryPlanning transDeliveryPlanning);
}

当我这样做时,仍然不能在删除前进行更新,我在这里还想念什么?

when i do this, still it's not update before delete, what did i still miss here?

推荐答案

尝试将@Transactional放在service方法内部的方法上方.例如:

try putting @Transactional above a method inside service method. e.g.:

@Service
public class MyService {

   @Autowired
   private MyRepo myRepo;

   @Autowired
   private MyRepo2 myRepo2;
   

   @Transactional
   public void yourTransactionService(arguments){
      *** your DML operations here ***
      e.g. 
      myRepo.save(blabla);
      myRepo.delete(blabla1);
      ...
      myRepo2.save(blabla2);
      myRepo3.delete(blabla3);
      ...

   }

}

这样,在调用yourTransactionService(arguments)时,所有DML都将保留或不保留.

This way when calling yourTransactionService(arguments) either all the DMLs are persisted or none of them persisted.

这篇关于如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆