Jul 15, 2013

Schedule Batch Apex in Summer '13

You could always schedule a Batch Apex before Summer '13.  Though, a new system method in this release did make it significantly easier to do.

Previously, I would create my batch class, with its batchable interface declared and its start, execute, and finish methods within.

Here's a sample batch class that runs through all of an org's Contacts and checks a box called myCheckbox__c, if it isn't already checked.

Then, to keep things tidy, I would create a 2nd class with the schedulable interface and a simple method.

Here's that schedulable class:

Then you could queue up the batch class by executing something like this:

Your job will be scheduled, on the hour, every hour.

You could have also implemented both the batchable and schedulable interfaces in the same class and provided a method to do your scheduling.

The new system.scheduleBatch() method that was included in Summer '13

You don't need to:
  1. Implement the schedulable interface (in the same or separate class)
  2. Create a Cron Schedule String (the '0 0 * * * ? *' string above) 
  3. Clean up finished jobs (scheduled jobs hang around until they are manually deleted or system.abortjob() takes care of them.  ScheduledApex clean up after themselves and are removed after running.
The above can be condensed into this:

And scheduled by calling:

Within the system.scheduleBatch() method 3 (and an optional 4th) parameters are provided:
  1. Instance of the batchable class
  2. The Job's name
  3. # of minutes to start the job in
  4. Scope size - 200 is the default for a batchable class' execute method.  This allows you to specify up to 2000 records per batch - just beware of hitting additional limits if you do.

Jul 7, 2013

New SOQL Clauses and System Fields

Summer' 13 and v28.0 brought a few new SOQL features for developers.  Included in those features are the FOR VIEW and FOR REFERENCE SOQL Clauses and their related LastViewedDate and LastReferencedDate date/time fields.  The new fields, unlike the other system date/time fields are dependent on the current user, meaning your values will be different from mine (illustrated below).

Let's define what a view and a reference are, per the release notes.  Records are considered:
Viewed - "when the user sees the details associated with it, but not when the user sees it in a list with other records."  
Referenced = "when a related record is viewed."
Here's a sample scenario to help understand these fields and how the clauses can be used.

User A creates a "Kirk Steffke" Contact record that is related to a CRM Science Account.  Upon creation, the LastViewedDate and LastReferencedDate for both will the same as the CreatedDate.

Contact:  Kirk Steffke

Account:  CRM Science

Notice above the LastViewedDate and LastReferencedDate fields.  These values are for User A, the user that created both records.  Observe closely and you'll notice that the Account's LastReferencedDate is slightly later than the LastViewedDate.  This is due to creating the Account record through the "New" button in the Contact's Account Lookup window.  The Account is first referenced upon the Account record's creation and a second time when User A is taken to the newly created Contact record.  The reference comes from the Account Lookup field on the Contact.

Since these two fields are user dependent, let's see how the data differs for another user that has never accessed either record.

Account:  CRM Science as viewed by User B

Contact:  Kirk Steffke as viewed by User B

The LastViewedDate has an impact certain areas of the user interface such as the Recent Items list in the toolbar or the items that quickly appear when using the search feature.  Below is a side by side comparison for the two different users.  The new Contact and Account records do not display in the quick search pop-down or in the Recent Items.

As seen here, just like the other sytem date/time fields, they aren't directly updatable.

However, the new SOQL clauses will do just that:

Don't expect to see an updated value when you run the above query; the query will update the LastReferencedDate for any rows returned as they are returned.  When you use the FOR REFERENCE or FOR VIEW clauses, the values returned will never be the actual values, they'll be the last values.  To see the actual values without updating them, use the original query where the clauses are omitted.