Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?_Java_Spring_Jpa_Spring Data Jpa_Spring Transactions - Fatal编程技术网

Java 如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?

Java 如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?,java,spring,jpa,spring-data-jpa,spring-transactions,Java,Spring,Jpa,Spring Data Jpa,Spring Transactions,您好,我试图实现的是使用Spring数据JPA和@Transactional annotation执行“更新”操作,然后执行“删除”操作,我希望两个操作都执行,但如果其中一个操作失败,我需要回滚,我如何正确执行 首先是我的服务课: @Transactional @Service public class TransDeliveryPlanningService { public ResponseRequest<TransDeliveryPlanning> deleteTra

您好,我试图实现的是使用Spring数据JPA和@Transactional annotation执行“更新”操作,然后执行“删除”操作,我希望两个操作都执行,但如果其中一个操作失败,我需要回滚,我如何正确执行

首先是我的服务课:

@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;
    }

}

当我这样做时,它仍然不是在删除之前更新,我还遗漏了什么?

尝试将
@Transactional
放在
服务
方法中的方法上方。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
或它们都不持久化。

有一种简单的方法,只需使用查询本身,就可以使用提交、事务和回滚


例如:您必须首先启动事务,然后需要将autocommit设置为0,以便在您对所有操作都满意后,将发生的每个事务都不会得到commit,否则您可以将语句传递为rollback这将回滚启动事务后所做的所有操作。为了更好地理解这一点,请使用以下

这是相同的结果,在myRepo.save(更新数据)中将不会执行,jpa直接执行myRepo.delete,有什么想法吗?在保存(更新)方法上方是否有修改?没有,my.save(object)函数是默认的jpa存储库函数,因此,我的存储库界面中没有@Modifying anotation。我也有同样的问题,这个答案以前对我有帮助:。因此,我必须定义own.save()函数并使用注释修改和查询,然后定义我自己的更新查询。你能帮我编写示例代码吗?链接是针对mysql的,我使用的是JPA Hibernate,我应该尽可能避免SQL查询层中的代码,如果问题可以通过JPA解决,我应该使用JPAIf。如果我正确理解,您需要首先更新一条记录,然后删除它,如果两个操作都可以,那么提交它们,否则回滚?看到你的代码,我觉得还可以。您启用了spring annotation事务管理吗?是的,我这样做是因为我需要创建审核日志数据,即我存储更新事件,然后是删除事件,是的,我通过将其添加到类的顶部来启用它,这是@Transactional的正确实现吗?我更喜欢在每个方法上放置
@Transactional
,而不是od类。通过启用spring事务管理,我的意思是尝试在spring配置类上添加注释
@EnableTransactionManagement
ohh,我没有放置该注释,也没有spring配置类,或者你指的是用@SpringBootApplication注释的主类,我必须放@EnableTransactionManagement?我通常有一个DB的配置类(我很老了,我喜欢控制:),在这个配置类上我添加了注释。我从没试过把它放在主课上。。你可以试试
@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);
      ...

   }

}