This quick test is made to test your basic understanding of Batch Apex.
- You can look at the syntax, bonus points if you don’t.
- The test should ideally not take more than 15 minutes to solve.
- All the criterias must be met.
- The answer is available at Admin2Dev GitHub Repo.
- The answer and complete breakdown of the program is available at the end of this page.
The Test
Question
- Insert 250 contacts with the last name "Test n" where n is a number starting from 1. For reference, the names should look like
Test 1
,Test 2
.. .Test 250
. - If a Contact with the last name
DeleteBatch
is created, it should run a Batch Apex Class that deletes all contacts with the last name "Test n" where n is a number. - When the Batch Apex finishes running, it should update the description of "Delete" contact with "Deleted records with ID
JobID
" where JobID should be the ID of the Batch Apex Class.
Hint
- Use
getJobID()
method onDatabase.batchableContext
variable to get the Job ID. - Use the escape character
\
to add'
to your Strings. So to write'Test'
, you have to write\'Test\'
instead. - The changes may not be visible instantly. Give it about 5 minutes before you see contacts being deleted and description updates.
Start a timer and note how long you take to solve. Ideally, it should take ~15 minutes, but don’t worry if you go overboard.
Answer
Inserting 250 records
- You can either create a class and call it from Anon Exec Window, or directly insert 250 records without classes.
List<Contact> finalList = new List<Contact>();
for(Integer i = 1; i<=250; i++){
Contact con = new Contact();
con.lastName = 'Test ' + i;
finalList.add(con);
}
insert finalList;
System.debug('Inserted ' + finalList.size() + ' records.');
Batch Apex
- My Batch Class is named
batchDeleter
.
global class batchDeleter implements Database.Batchable<sObject> {
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id, LastName FROM Contact WHERE LastName LIKE \'Test%\'');
}
global void execute(Database.BatchableContext bc, List<sObject> deleteList){
delete deleteList;
}
global void finish(Database.BatchableContext bc){
List<Contact> con = [SELECT Id, LastName FROM Contact WHERE LastName = 'DeleteBatch' LIMIT 1];
List<Contact> finalList = new List<Contact>();
for (Contact iterator: con){
iterator.Description = 'Deleted records with ID ' + bc.getJobId();
finalList.add(iterator);
}
update finalList;
}
}
- First we return all values that have Last Name
Test%
where%
is a wildcard. - In the execute method, we simply delete the entire list.
- In the finish method, we select the 'DeleteBatch' contact and to be really sure we get only 1 value, we use
Limit
keyword. - Now we iterate over our list and update it's description to match the batch job id.
bc
comes from the method parameterDatabase.BatchableContext bc
and running.getJobId()
returns the ID.
- Then the values are commited to the database using the
update
statement.
Trigger
- We want the Batch Class to be executed when the record is finished inserting, so writing a trigger with a helper class is the only way we can control our batch class execution.
Trigger File
trigger LastName on Contact(after insert){
if (Trigger.isAfter){
if (Trigger.isInsert){
LastNameHelper.deleteContacts(trigger.new);
}
}
}
Tigger Helper File
public class LastNameHelper{
public static void deleteContacts(List<Contact> newList){
for(Contact iterator: newList){
if (iterator.LastName == 'DeleteBatch'){
batchDeleter runBatch = new batchDeleter();
Database.executeBatch(runBatch);
}
}
}
}
- In our Helper Class, every time a new contact is inserted we use
Trigger.new
to pass all records, and in the helper class check for last name. If the last name matches our condition, we run the Batch Class.