简体   繁体   中英

Repository is null in job scheduling in spring boot with quartz scheduler

When the user calls the api /bet/{id}/start, the Schedule will immediately be created with name = id, group = Exchanges, every 3rd second on the minute it will automatically call the excute function to process, for example here I will call the findById(id) function of the repository to retrieve and process the data, but the result I get is java.lang.NullPointerException: null

BetController.java

@RestController
@RequestMapping("/api")
@Transactional
public class BetController extends AbstractController {

    private MainScheduler mainScheduler;
    
    @RequestMapping(value = "/bet/{id}/start", method = RequestMethod.POST)
    public String addAndStartScheduleWithBetId(@PathVariable("id") Long id) {
        mainScheduler.addAndStartScheduler(""+id);
        
        return "";
    }
}

MainScheduler.java

@Service
public class MainScheduler {
    
    private Scheduler scheduler;
    
    public MainScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }
    
    public Scheduler addAndStartScheduler(String betId) {
        try {
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(betId,"Exchanges").withSchedule(CronScheduleBuilder.cronSchedule("3 * * ? * * *")).build();
            JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(betId, "Exchanges") .build();
            scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();
            scheduler.scheduleJob(jobDetail, trigger);
            System.out.println(jobDetail.getKey() + ","+ trigger.getKey() + " will run at: " + new Date());
        } catch(Exception ex) {
            System.out.println(ex);
        }
        return scheduler;
    }
    
    public boolean deleteJobDetail(String name) {
        boolean flag = false;
        try {
            flag = scheduler.deleteJob(jobKey(name, "Exchanges"));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return flag;
    }
    
}

BetRepository.java

public interface BetRepository extends CrudRepository<Bet, Long> {

    Page<Bet> findAll(Pageable pageable);

    Optional<Bet> findById(Long id) ;
}

ScheduleJob.java

public class ScheduleJob implements Job{
    
    @Autowired
    private BetRepository betRepository;
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // TODO Auto-generated method stub
        System.out.println("key+group trigger: " + context.getTrigger().getKey());
        Long id = Long.parseLong(context.getJobDetail().getKey().getName());
        System.out.println("Bet repositorys: " + betRepository.findById(id));
    }
    
}
13-07-2021 03:33:03.015 [35m[DefaultQuartzScheduler_Worker-3][0;39m
                [1;31mERROR[0;39m
                org.quartz.core.ErrorLogger.schedulerError - Job (Exchanges.5 threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.NullPointerException: null
    at com.bot.auto.utils.ScheduleJob.execute(ScheduleJob.java:21)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    ... 1 common frames omitted

Modify your MainScheduler so that you get the autowired BetRepository and put it in the scheduler context before starting the schedular and get it in the Job.

    @Service
    public class MainScheduler {
        
        private Scheduler scheduler;
        @Autowired
        private BetRepository betRepository;
    
        public MainScheduler(Scheduler scheduler) {
            this.scheduler = scheduler;
        }
        
        public Scheduler addAndStartScheduler(String betId) {
            try {
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity(betId,"Exchanges").withSchedule(CronScheduleBuilder.cronSchedule("3 * * ? * * *")).build();
                JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(betId, "Exchanges") .build();
                scheduler = StdSchedulerFactory.getDefaultScheduler();
                schduler.getContext().put("betRepo",betRepository);
                scheduler.start();
                scheduler.scheduleJob(jobDetail, trigger);
                System.out.println(jobDetail.getKey() + ","+ trigger.getKey() + " will run at: " + new Date());
            } catch(Exception ex) {
                System.out.println(ex);
            }
            return scheduler;
        }
<    -----other methods as is---->
    }

Change your Job class as below

public class ScheduleJob implements Job{

private BetRepository betRepository;

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    // TODO Auto-generated method stub
 betRepository=    context.get("betRepo"); or context.getScheduler().getContext().get("betRepo");
    System.out.println("key+group trigger: " + context.getTrigger().getKey());
    Long id = Long.parseLong(context.getJobDetail().getKey().getName());
    System.out.println("Bet repositorys: " + betRepository.findById(id));
}

}

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