Schedule Batch Jobs in - OpportunityPartner Example

Posted by Craig Probus
Craig Probus”


Welcome to our Salesforce Blog section as part of our Revenue Technology Series!

Have you tried to create a trigger when an Opportunity’s Partner related list is updated? If you have tried, then you have failed as it is not possible. The OpportunityPartner object is not available to create triggers on, so it becomes a problem when you need to invoke business logic when a Partner is modified on an Opportunity.


The solution is to create a Scheduled Batch Job, to run every 15 minutes to invoke the needed business process or update the related metrics. This is easy to do, just follow the below instructions.

  1. Create an Apex class implementing two interfaces
    (Database.Batchable & Schedulable)
  2. Schedule the job


Create an Apex class, implement the Database.Batchable & Schedulable interfaces

You will need to create the following methods to meet requirements for the Database.Batchable interface:

global Database.QueryLocator start(Database.BatchableContext BC)
  • This is the first method invoked
  • Use this method to query SFDC for the objects you want to work on
  • Note: there is another way to return the objects to be worked on, using an iterable. I would not recommend this as you are stuck using the governor limits of SOQL!


global void execute(Database.BatchableContext BC, List scope)
  • This is where the “magic” happens; implement your business logic here


global void finish(Database.BatchableContext BC)
  • This is the last method invoked
  • Use this method for notification emails or create a logging record to track the outcome


You will need to create one method for the Schedulable interface:

global void execute(SchedulableContext SC)
  • This method is invoked by the SFDC Scheduler (don’t be confused by the other execute() method listed above)
  • All you do here is instantiate the class you created and pass it to the scheduler


Schedule the job

In Eclipse, open up the “Execute Anonymous” window to execute the following syntax…

YourClass x = new YourClass();

String s = '0 0 * * * ?';

system.schedule('Every hour job', s, x);


Full Code:

global class JobPartnerMetricUpdate implements Database.Batchable, Schedulable
  String query = 'SELECT AccountToId FROM OpportunityPartner WHERE IsPrimary = true';
  *  constructor
  global JobPartnerMetricUpdate() {

  *  execute(SchedulableContext SC)
  global void execute(SchedulableContext SC) {
    // invoke business logic - this method is strictly to invoke
    // the method from the scheduler...
    JobPartnerMetricUpdate partnerMetrics = new JobPartnerMetricUpdate();
    ID batchprocessid = Database.executeBatch(partnerMetrics);

  *  start(Database.BatchableContext BC)
  global Database.QueryLocator start(Database.BatchableContext BC) {
    return Database.getQueryLocator(this.query);

  *  execute(Database.BatchableContext BC, List scope)
  global void execute(Database.BatchableContext BC, List scope) {
    // collections to hold distinct list of IDs
    Set distinctAccountIDs = new Set();
    // loop through query results...
    for(Integer i = 0; i < scope.size(); i++) {
      OpportunityPartner opptyPartner = (OpportunityPartner) scope[i];
      // if we have not already processed this Account ID, go for it... (avoid processing same Account twice)
      if(!distinctAccountIDs.contains(opptyPartner.AccountToId)) {
        // update Account records
        RCAccount rcAcct = new RCAccount(opptyPartner.AccountToId);
        // add Account ID to the collection so that we don't process the same Account twice...

  *  finish(Database.BatchableContext BC)
  global void finish(Database.BatchableContext BC) {
  //TODO: add a record to custom log object

Free Salesforce Consultation




Subscribe to Blog