与 ExecutorService 一起使用时,Hibernate 不会抛出任何错误,也不会将记录保存在数据库中

Hibernate not throwing any error nor saving the record in database when used with ExecutorService

为什么 JPARepository.save 方法在 ExecutorService 任务中使用时不起作用?

@Component
public class Testing {
@Inject
JobSummaryRepository jobSummaryRepository;
private Logger log = LoggerFactory.getLogger(JobSummary.class);

@PostConstruct
public void Save(){
    JobSummary js = new JobSummary();
    js.setCount(1L);
    js.setCity_id(1L);
    js.setCompany_id(1L);
    js.setDate(new Date());
    js.setJob_master_id(1L);
    js.setHub_id(1L);
    js.setUser_id(1L);
    js.setJob_status_id(1L);

    ExecutorService executor = Executors.newFixedThreadPool(10);
    Future<String> future = executor.submit(this.CallablecustomSaveOrUpdate(js));
    try {
        future.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (Exception e){
        e.printStackTrace();
    } finally {
        log.info("What!!");
    }
    //jobSummaryRepository.save(js);
    executor.shutdown();
}
private Callable<String> CallablecustomSaveOrUpdate(JobSummary js){
    return () -> {
        jobSummaryRepository.save(js);
        return "Done";
    };
}

}

上面的代码没有抛出任何错误,也没有在数据库中保存任何数据。 finally 块也没有执行。

另一方面,注释掉 ExecutorService 逻辑并直接调用 jobSummaryRepository.save(js) 工作得很好。

我无法理解这个问题。

也许您可以尝试将 jobSummaryRepository.save(js) 放入 Runnable 中,然后将此 Runnable 的实例传递给执行程序服务,看看是否可行

可运行示例:

public class MyRunnable implements Runnable {
    private JobSummary js;
    private JobSummaryRepository jobSummaryRepository;

    public MyRunnable(JobSummary js, JobSummaryRepository jsp) {
        this.js = js;
        this.jobSummaryRepository = jsp;
    }

    public void run() {
        js.setCount(1L);
        js.setCity_id(1L);
        js.setCompany_id(1L);
        js.setDate(new Date());
        js.setJob_master_id(1L);
        js.setHub_id(1L);
        js.setUser_id(1L);
        js.setJob_status_id(1L);
        jobSummaryRepository.save(js);
    }
}

那么您的测试 class 可能如下所示

public class Testing {

    public void testSave() {

        ExecutorService executor = Executors.newFixedThreadPool(10);
        Future future = executor.submit(new MyRunnable(new JobSummary(), new JobSummaryRepository()));
        try {
            future.get();
        }
        ...
        ...
        executor.shutdown();
    }
}

我认为 @PostConstruct 是导致问题的原因。因为它是在加载所有 spring component/context 之前调用的。 为此,您可以使用 spring 的 ContextRefreshedEvent

简单示例:

@Component
public Test implements ApplicationListener<ContextRefreshedEvent> {
@Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
   //do something if all apps have initialised
  }
}

希望这会奏效。