Невозможно сохранить работу, поскольку она уже существует с этим идентификатором

Я новичок в Quartz. Мне удалось установить его и запустить. Но у меня есть ошибка, когда я запускаю ее во второй раз, потому что эта работа уже существует с этим идентификатором.

Здесь мой код:

public void scheduleJobs() throws Exception {

    try {
        int i = 0;

        scheduler = new StdSchedulerFactory().getScheduler();

        JobKey job1Key = JobKey.jobKey("job"+i, "my-jobs"+i);
        JobDetail job1 = JobBuilder
                .newJob(SimpleJob.class)
                .withIdentity(job1Key)
                .build();

        TriggerKey tk1 = TriggerKey.triggerKey("trigger"+i, "my-jobs"+i);
        Trigger trigger1 = TriggerBuilder
                .newTrigger()
                .withIdentity(tk1)
                .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(11, 25))
                .build();

        scheduler.start(); // start before scheduling jobs
        scheduler.scheduleJob(job1, trigger1);
        i++;

        printJobsAndTriggers(scheduler);

    } catch (SchedulerException e) {
        LOG.error("Error while creating scheduler", e);
    }   
}

Я попытался использовать целое число я для изменения имени, но оно не работает. Вы знаете, как я могу это исправить? Большое спасибо.

Ответ 1

Вы можете:

  • проверить, существует ли уже "ключ задания" и удалить существующее задание перед созданием нового:

    scheduler.deleteJob(job1Key);

  • или создайте новое задание с другим ключом (в вашем случае каждый раз, когда вы выполняете scheduleJobs(), переменная i имеет то же значение (0)

  • или просто повторно использовать одну и ту же работу (зачем было бы создавать новое задание, если старый все еще хорош)

  • или используйте хранилище данных RAM, которое не сохраняет задания в базе данных (каждый раз, когда вы будете использовать свое программное обеспечение, у вас будет пустое хранилище заданий)

Это действительно зависит от того, что вы хотите делать с вашими заданиями!

Ответ 2

Это не прямой ответ на конкретный код, указанный в вопросе, но я не заметил его при поиске в другом месте и думал, что это может быть полезно для будущих читателей:

Если вы находитесь в ситуации, когда у вас есть существующий Job, но просто хотите добавить новый Trigger, вы можете позвонить:

scheduler.ScheduleJob(trigger);

и он добавит Trigger к Job, не пытаясь воссоздать Job. Единственный трюк в том, что вы должны убедиться, что Trigger JobKey верен.

Мой общий код для этого взаимодействия выглядит примерно так:

IJobDetail job;   // Handed in
ITrigger trigger; // Handed in

// Keeping track of this because we need to know later whether it new or not
var newJob = job == null;
if (newJob)
{
    job = JobBuilder.Create<TargetJob>()
                 .WithIdentity([whatever]) 
                 [.OtherConfiguration()]
                 .Build();
}

var trigger = TriggerBuilder
    .Create()
    .WithIdentity([whatever])
    // ** Gotcha #1: Make sure it linked to the job **
    .ForJob(job.Key) 
    [.OtherConfiguration()]
    .Build();

if (newJob)
{
    _scheduler.ScheduleJob(job, trigger);
}
else
{
    // ** Gotcha #2: Make sure you don't reschedule the job **
    _scheduler.ScheduleJob(trigger);
}

Ответ 3

Проверьте существующую работу перед планированием:

JobDetail job;
SimpleTrigger trigger;

//Create your trigger and job

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();

if (scheduler.checkExists(job.getKey())){
    scheduler.deleteJob(job.getKey());
}
scheduler.scheduleJob(job, trigger);

Ответ 4

Если кто-то из вас сталкивается с той же проблемой, и ваше решение находится на С#. Вот как вы можете исправить эту ошибку.

Здесь мы настраиваем планировщик.

public async Task StartAsync(CancellationToken cancellationToken) {
    try {
        var scheduler = await GetScheduler();
        var serviceProvider = GetConfiguredServiceProvider();
        scheduler.JobFactory = new CustomJobFactory(serviceProvider);
        await scheduler.Start();
        await ConfigureDailyJob(scheduler);
    }
    catch(Exception ex) {
        _logger.Error(new CustomConfigurationException(ex.Message));
    }
}

Это то, как мы можем настроить задание. Обратите внимание, что мы проверяем, есть ли уже задание, и если await scheduler.CheckExists(dailyJob.Key) возвращает true, мы удаляем эту информацию о задании и создаем новую с тем же ключом.

private async Task ConfigureDailyJob(IScheduler scheduler) {
    var dailyJob = GetDailyJob();
    if (await scheduler.CheckExists(dailyJob.Key)) {
        await scheduler.DeleteJob(dailyJob.Key);
        _logger.Info($ "The job key {dailyJob.Key} was already existed, thus deleted the same");
    }
    await scheduler.ScheduleJob(dailyJob, GetDailyJobTrigger());
}

Есть поддерживающие частные функции.

private IJobDetail GetDailyJob() {
    return JobBuilder.Create < IDailyJob > ().WithIdentity("dailyjob", "dailygroup").Build();
}
private ITrigger GetDailyJobTrigger() {
    return TriggerBuilder.Create().WithIdentity("dailytrigger", "dailygroup").StartNow().WithSimpleSchedule(x = >x.WithIntervalInHours(24).RepeatForever()).Build();
}

Вы можете получить полный исходный код из этого репозитория GitHub.

Ответ 5

Вы можете создавать новые задания, принимая я как статический int. И вместо "job" + я это будет "job" + Integer.toString(i). Это сработало для меня.