Majestic
Majestic

Reputation: 938

Unable to store job because one already exists with this identification

I'm new with Quartz. I succeeded to install it and run it. But I have an error when I run it for the second time because the job already exists with this identification.

Here my code :

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);
    }   
}

I tried to use an integer i to change the name but it does not work. Do you have any idea how can I fix it? Many thanks.

Upvotes: 19

Views: 41916

Answers (5)

Sibeesh Venu
Sibeesh Venu

Reputation: 21849

If anyone of you are facing the same issue and your solution is in C#. This is how you can fix this error.

This is where we configure the scheduler.

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));
    }
}

This is how we can configure the Job, please be noted that we are checking whether the job is already there, and if the await scheduler.CheckExists(dailyJob.Key) returns true, we delete that job info and create a new one with the same key.

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());
}

There are the supporting private functions.

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();
}

You can get the complete source code from this GitHub repository.

Upvotes: 4

Oleg Mikhailov
Oleg Mikhailov

Reputation: 6081

Check for existing job before scheduling:

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);

Upvotes: 18

Rushi Pradhan
Rushi Pradhan

Reputation: 21

You can create new jobs by taking i as a static int. And instead of "job"+i it would be "job"+ Integer.toString(i) . It worked for me.

Upvotes: -1

eouw0o83hf
eouw0o83hf

Reputation: 9598

This is not a direct answer to the specific code listed in the question, but I didn't notice it when searching elsewhere and thought this might be useful for future readers:

If you're in a situation where you have an existing Job but just want to add a new Trigger, you can call:

scheduler.ScheduleJob(trigger);

and it will add the Trigger to the Job without trying to recreate the Job. The only trick is that you have to make sure the Trigger's JobKey is correct.

My overall code for this interaction looks roughly like:

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

// Keeping track of this because we need to know later whether it's 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's 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);
}

Upvotes: 11

olivierlemasle
olivierlemasle

Reputation: 1229

You can:

  • check if the "job key" already exists, and remove the existing job before creating a new one:

    scheduler.deleteJob(job1Key);

  • or create a new job with another key (in your case, each time you execute scheduleJobs(), variable i has the same value (0)

  • or just re-use the same job (why would you create a new job if the old one is still good)

  • or use the RAM Job Store, which does not persist jobs in database (each time you will use your software, you will have an empty job store)

It really depends on what you want to do with your jobs!

Upvotes: 19

Related Questions