与 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
}
}
希望这会奏效。
为什么 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
}
}
希望这会奏效。