docs/documentation/quartz-2.x/migration-guide.md
This document outlines changes needed per version upgrade basis. You need to check the steps for each version you are jumping over. You should also check the complete change log.
If you are a new user starting with the latest version, you don't need to follow this guide. Just jump right to the tutorial
Database schema has changed to include the scheduled time for fired triggers table. You need to run the migration script:
database\schema_20_to_22_upgrade.sql
Make sure you check the scheduler name in the script - the default value of sched_name column is TestScheduler! If you have existing data the scheduler name should correspond to your existing scheduler name in Quartz configuration (quartz.scheduler.instanceName).
There are variations for different database server inside the script. Choose the one suiting you the best.
Database has changed since 1.0 version. You need to run the database migration script:
database\sqlserver_schema_10_to_20_upgrade.sql
The script is made for SQL Server, but should work for others. You can adapt the script when needed for your specific database. Always test the migration on non-production server before upgrading production
The most obvious differences with version 2.0 are the significant changes to the API. These changes have aimed to: modernize the API to use collections and generics, remove ambiguities and redundancies, hide/remove methods that should not be public to client code, improve separation of concerns, and introduce a Domain Specific Language (DSL) for working with the core entities (jobs and triggers).
While the API changes are significant, and the usage of the "new way of doing things" is highly encouraged, there are some formulaic (search-and-replace) techniques that can be used to get 1.x code quickly working with version 2.0. See the migration guide for more information.
Outline of most significant API changes:
API methods that return (or take as parameters) arrays now return (or take) typed collections. For example, rather than GetJobGroupNames(): string[] we now have GetJobGroupNames(): IList<string> Job and Trigger identification is now based on JobKey and TriggerKey. Keys include both a name and group. Methods which operate on particular jobs/triggers now take keys as the parameter. For example, GetTrigger(TriggerKey key): ITrigger, rather than GetTrigger(string name, string group): Trigger. ITrigger is now an interface, rather than a class. Likewise for ISimpleTrigger, ICronTrigger, etc. New DSL/builder-based API for construction Jobs and Triggers:
IJobDetail job = JobBuilder.Create<SimpleJob>()
.WithIdentity("job1", "group1")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartAt(DateBuilder.FutureDate(2, IntervalUnit.Hour))
.WithSimpleSchedule(x => x.RepeatHourlyForever())
.ModifiedByCalendar("holidays")
.Build();
Methods from TriggerUtils related to easy construction of Dates have been moved to new DateBuilder class, that can be used with static imports to nicely create Date instances for trigger start and end times, etc.
// build a date for 9:00 am on Halloween
DateTimeOffset runDate = DateBuilder.DateOf(0, 0, 9, 31, 10);
// build a date 2 hours in the future
DateTimeOffset myDate = DateBuilder.FutureDate(2, IntervalUnit.Hour);
The IStatefulJob interface has been deprecated in favor of new class-level attributes for IJob implementations (using both attributes produces equivalent to that of the old IStatefulJob interface):
// instructs the scheduler to re-store the Job's JobDataMap contents after execution completes
[PersistJobDataAfterExecution]
public class MyJob : IJob
{
}
// instructs the scheduler to block other instances of the same job (by JobKey) from executing when one already is
[DisallowConcurrentExecution]
public class MyJob : IJob
{
}
Significant changes to usage of JobListener and TriggerListener
Other changes
Various performance improvements, including (but not limited to):