我偶尔需要更新作业上的触发器。 我的触发器只发射一次,起火日期可能会有所不同。
所以我有一个管理这种情况的JobManager。我的想法是检查给定的jobDetail是否已经存在,然后将其删除并创建一个新的,但是我得到了奇怪的行为和这个异常。
所以我的控制器调用jobManager.createJob(interruttore, richiesta);
,即:
public void createJob(Interruttore interruttore, Date richiesta) throws SchedulerException {
JobDetail jobDetail = createJobDetail(interruttore);
createOrUpdateScheduledJobs(interruttore, jobDetail, richiesta);
}
这是createJob
public JobDetail createJobDetail(Interruttore interruttore) throws SchedulerException {
if (scheduler.getScheduler().checkExists(JobKey.jobKey("JobDetail" + interruttore.getNomeInterruttore()))) {
logger.debug("jobDetail already present, delete it");scheduler.getScheduler().deleteJob(JobKey.jobKey("JobDetail" + interruttore.getNomeInterruttore()));
}
logger.debug("Il jobDetail non esiste, lo creo");
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass(TimeoutJob.class);
jobDetailFactoryBean.setName("JobDetail" + interruttore.getNomeInterruttore());
jobDetailFactoryBean.setGroup("timeoutJobDetail");
jobDetailFactoryBean.setDescription("Job for timeout");
jobDetailFactoryBean.setDurability(true);
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("idInterruttore", interruttore.getIdInterruttore());
jobDetailFactoryBean.setJobDataAsMap(map);
jobDetailFactoryBean.afterPropertiesSet();
logger.debug("JobDetail is " + jobDetailFactoryBean.toString());
return jobDetailFactoryBean.getObject();
}
和createOrUpdateScheduledJobs(interruttore, jobDetail, richiesta);
如下
public void createOrUpdateScheduledJobs(Interruttore interruttore, JobDetail jobDetail,
Date richiesta) throws SchedulerException {
// check if trigger exists
boolean triggerExist = scheduler.getObject().checkExists(
TriggerKey.triggerKey("myTrigger" + interruttore.getNomeInterruttore(), "timeoutTriggers"));
logger.debug("Trigger exists? :" + triggerExist);
if (triggerExist) { //replace trigger and reschedule job
SimpleTrigger oldTrigger = (SimpleTrigger) scheduler.getScheduler().getTrigger(
TriggerKey.triggerKey("myTrigger" + interruttore.getNomeInterruttore(), "timeoutTriggers"));
TriggerBuilder<SimpleTrigger> tb = oldTrigger.getTriggerBuilder();
SimpleTrigger newTrigger = tb.startAt(richiesta).build();
scheduler.getScheduler().rescheduleJob(((SimpleTrigger) oldTrigger).getKey(), newTrigger);
logger.debug("new Trigger with firetime " + newTrigger.getNextFireTime());
} else { // create a new one
// creo il trigger e lo schedulo il job
SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
trigger.setName("myTrigger" + interruttore.getNomeInterruttore());
trigger.setGroup("timeoutTriggers");
trigger.setJobDetail(jobDetail.getObject());
trigger.setStartTime(richiesta);
trigger.setRepeatCount(0);
trigger.afterPropertiesSet();
try {
scheduler.getScheduler().scheduleJob(jobDetail, trigger.getObject());
} catch (SchedulerException e) {
logger.error("Errore: ", e);
}
logger.debug("Trigger object is :" + trigger.getObject());
}
}
当我启动应用程序时,一切正常,然后第二次我的控制器调用方法我得到异常
org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'timeoutJobDetail.JobDetailZona -2A', because one already exists with this identification.
创建新jobDetail的方法没有找到要删除的先前jobDetail实例,但是在创建新实例时,它确实发现它确实存在...
答案 0 :(得分:0)
TriggerKey和JobKey由Name和Group组成。
因此,您需要在TriggerKey和JobKey中指定Group,与SimpleTriggerFactoryBean和JobDetailFactoryBean相同。
抱歉,我没有正确检查,但是当我更改JobKey和TriggerKey时。第二次在createJobDetail方法中调用Scheduler.deleteJob()方法。