Make a class to batch an existing class?Build Custom Batch Queue to centrally manage Batches & circumvent the Max. 5 Batches in parallelAn interface extending a system interface causes process hangs?Code efficiency help: Can't avoid CPU limit (even with batch)Scheduled Apex not consistantly executing, sending emailsExecute Anonymous works with trigger, Test Class Doesn'tCode coverage for class run via Execute AnonymousTestmethod problem: System.QueryException: List has no rows for assignment to SObjectBatch Apex class failure - CPU time limit exceededHow to call apex method from command button on custom visualforce pageTest coverage for a relative date method
Do people who work at research institutes consider themselves "academics"?
Why aren't 1.e4 g6 2.d4 Bh6, and 1.e4 b6 2.d4 Ba6 not considered by theory?
Slice a list based on an index and items behind it in python
What metal is most suitable for a ladder submerged in an underground water tank?
Can my American children re-enter the USA by International flight with a passport card? Being that their passport book has expired
Given 0s on Assignments with suspected and dismissed cheating?
Holding rent money for my friend which amounts to over $10k?
Why are goodwill impairments on the statement of cash-flows of GE?
How to not get blinded by an attack at dawn
Proper way to use apply_filters() with class functions?
What dog breeds survive the apocalypse for generations?
Why did the soldiers of the North disobey Jon?
Looking for source for a "yield space" rule my 3.5 group uses
Is there an academic word that means "to split hairs over"?
Does the wearer know what items are in which patch in the Robe of Useful items?
I recently started my machine learning PhD and I have absolutely no idea what I'm doing
Does the Rogue's Reliable Talent work for Thieves' tools, if the rogue is proficient in them?
Why can't I share a one use code with anyone else?
Network latencies between opposite ends of the Earth
Why would someone open a Netflix account using my Gmail address?
What did farmers do in Japan?
Is there any good reason to write "it is easy to see"?
Meaning of "legitimate" in Carl Jung's quote "Neurosis is always a substitute for legitimate suffering."
Why commonly or frequently used fonts sizes are even numbers like 10px, 12px, 16px, 24px, or 32px?
Make a class to batch an existing class?
Build Custom Batch Queue to centrally manage Batches & circumvent the Max. 5 Batches in parallelAn interface extending a system interface causes process hangs?Code efficiency help: Can't avoid CPU limit (even with batch)Scheduled Apex not consistantly executing, sending emailsExecute Anonymous works with trigger, Test Class Doesn'tCode coverage for class run via Execute AnonymousTestmethod problem: System.QueryException: List has no rows for assignment to SObjectBatch Apex class failure - CPU time limit exceededHow to call apex method from command button on custom visualforce pageTest coverage for a relative date method
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Not sure if this is possible. I've got a data factory class for my sandbox. If I run all the methods (I do it in Execute Anonymous) on that class then I end up with data I (reasonably) want in my sandbox. But I have to break up running all the methods into several pieces or I hit limits. (Even in the chunks I have I get some warnings due to NPSP triggers.) Is there a way I could easily take those chunks I've separated and make a batchable class that would run them all by issuing just one command rather than having to open Execute Anonymous eight times in sequence?
[And by "easily," I mean something that I could understand. I'm pretty much a newbie coder.]
I can't put in my full data factory code because my post ends up too long.
Here are the chunks I have to use for Execute Anonymous:
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
apex batch
add a comment |
Not sure if this is possible. I've got a data factory class for my sandbox. If I run all the methods (I do it in Execute Anonymous) on that class then I end up with data I (reasonably) want in my sandbox. But I have to break up running all the methods into several pieces or I hit limits. (Even in the chunks I have I get some warnings due to NPSP triggers.) Is there a way I could easily take those chunks I've separated and make a batchable class that would run them all by issuing just one command rather than having to open Execute Anonymous eight times in sequence?
[And by "easily," I mean something that I could understand. I'm pretty much a newbie coder.]
I can't put in my full data factory code because my post ends up too long.
Here are the chunks I have to use for Execute Anonymous:
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
apex batch
alternative: consider vendor product: Gearset
– cropredy
2 hours ago
add a comment |
Not sure if this is possible. I've got a data factory class for my sandbox. If I run all the methods (I do it in Execute Anonymous) on that class then I end up with data I (reasonably) want in my sandbox. But I have to break up running all the methods into several pieces or I hit limits. (Even in the chunks I have I get some warnings due to NPSP triggers.) Is there a way I could easily take those chunks I've separated and make a batchable class that would run them all by issuing just one command rather than having to open Execute Anonymous eight times in sequence?
[And by "easily," I mean something that I could understand. I'm pretty much a newbie coder.]
I can't put in my full data factory code because my post ends up too long.
Here are the chunks I have to use for Execute Anonymous:
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
apex batch
Not sure if this is possible. I've got a data factory class for my sandbox. If I run all the methods (I do it in Execute Anonymous) on that class then I end up with data I (reasonably) want in my sandbox. But I have to break up running all the methods into several pieces or I hit limits. (Even in the chunks I have I get some warnings due to NPSP triggers.) Is there a way I could easily take those chunks I've separated and make a batchable class that would run them all by issuing just one command rather than having to open Execute Anonymous eight times in sequence?
[And by "easily," I mean something that I could understand. I'm pretty much a newbie coder.]
I can't put in my full data factory code because my post ends up too long.
Here are the chunks I have to use for Execute Anonymous:
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
apex batch
apex batch
asked 6 hours ago
Michael KolodnerMichael Kolodner
847
847
alternative: consider vendor product: Gearset
– cropredy
2 hours ago
add a comment |
alternative: consider vendor product: Gearset
– cropredy
2 hours ago
alternative: consider vendor product: Gearset
– cropredy
2 hours ago
alternative: consider vendor product: Gearset
– cropredy
2 hours ago
add a comment |
3 Answers
3
active
oldest
votes
You can use the chaining mechanism i.e. you can call your same batch class from finish method but with different parameters which you can pass via constructor of batch class. In this way, you can mention which methods needs to be called in that specific run.
For this, you can have your entire code of data factory in execute method of batch class, just that you will have to segregate your methods so that it will execute only few methods at a time i.e. whichever is passed as parameter.
Sample batch class would look like this
global class CreateSampleData implements Database.Batchable<sObject>, Database.Stateful
String runChunk;
global CreateSampleData(String strRunFor)
runChunk = strRunFor;
global Database.QueryLocator start(Database.BatchableContext BC)
return Database.getQueryLocator([SELECT Id, Name FROM Organization]);
global void execute(Database.BatchableContext BC, List<sObject> scope)
if(runChunk=='First Chunk')
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
else if (runChunk=='Second Chunk')
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
else if (runChunk=='Third Chunk')
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
else if(runChunk=='Fourth Chunk')
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
global void finish(Database.BatchableContext BC)
if(runChunk=='First Chunk')
runChunk = 'Second Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Second Chunk')
runChunk = 'Third Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Third Chunk')
runChunk = 'Fourth Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
You can call this batch class from anonymous window with single line
Database.executeBatch(new CreateSampleData('First Chunk'));
Note : You can have meaningful names for all the chunks, you will have to make that respective changes in the code as well. Also, you can segregate the chunks to have data factory methods according to the volume of data each method is creating.
Also, make sure that batch does not go into recursion. All your conditions should be properly written in finish method, and don't add an else clause in finish method.
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
add a comment |
It's certainly possible, but I wouldn't qualify it as easy. The way I would do it is to write a SandboxPostCopy script that enqueued a batch class.
This seems like a good spot to use the relatively rare batch class that iterates over a primitive or enumerated type, rather than an sObject query. The execute() method can then look at the current entity with a switch on statement and decide which batch of methods to call. I think the skeleton would look like this, and I'm cribbing some of the structure from the Nonprofit Success Pack's telemetry batches:
// define an enum somewhere
public enum PostCopyStep
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// and so on
Then, the batch class looks kind of like this, allowing it to iterate over a list of post copy steps in units of one and execute each in a separate transaction.
public without sharing class PostcopySandboxPopulationbBatch implements Database.Batchable<PostCopyStep>
private static final List<PostCopyStep> postCopySteps = new List<PostCopyStep>
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// etc.
;
public Iterable<PostCopyStep> start(Database.BatchableContext bc)
if (!Test.isRunningTest())
return postCopySteps;
else
return new List<PostCopyStep>JediStudents; // can't run multiple batches in a test.
public void execute(Database.BatchableContext bc, List<PostCopyStep> step)
switch on (step[0])
when JediStudents
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
when StarWarsPrograms
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
// etc.
public void finish(Database.BatchableContext bc)
Your post copy class would run the batch using a batch size of 1.
The additional trick is that you'll have to write test classes to validate the batch class before you can deploy it to production, and because there are so many logical branches involved it may be rather tedious. This is a place where I'd generally just call the execute() method directly in a test class (supplying each enum value in sequence) rather than trying to actually enqueue the batch.
Another approach to this is to use aninterface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.
– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
add a comment |
Take the basic structure of a batch class: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Start, execute, finish.
Then chain the batches together. So batch 1 would execute be two or 3 methods and then finish would point to batch 2, which would execute 2 or 3 methods depending on how big they are. And so on and so on till you've got them all.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "459"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f262339%2fmake-a-class-to-batch-an-existing-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use the chaining mechanism i.e. you can call your same batch class from finish method but with different parameters which you can pass via constructor of batch class. In this way, you can mention which methods needs to be called in that specific run.
For this, you can have your entire code of data factory in execute method of batch class, just that you will have to segregate your methods so that it will execute only few methods at a time i.e. whichever is passed as parameter.
Sample batch class would look like this
global class CreateSampleData implements Database.Batchable<sObject>, Database.Stateful
String runChunk;
global CreateSampleData(String strRunFor)
runChunk = strRunFor;
global Database.QueryLocator start(Database.BatchableContext BC)
return Database.getQueryLocator([SELECT Id, Name FROM Organization]);
global void execute(Database.BatchableContext BC, List<sObject> scope)
if(runChunk=='First Chunk')
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
else if (runChunk=='Second Chunk')
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
else if (runChunk=='Third Chunk')
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
else if(runChunk=='Fourth Chunk')
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
global void finish(Database.BatchableContext BC)
if(runChunk=='First Chunk')
runChunk = 'Second Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Second Chunk')
runChunk = 'Third Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Third Chunk')
runChunk = 'Fourth Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
You can call this batch class from anonymous window with single line
Database.executeBatch(new CreateSampleData('First Chunk'));
Note : You can have meaningful names for all the chunks, you will have to make that respective changes in the code as well. Also, you can segregate the chunks to have data factory methods according to the volume of data each method is creating.
Also, make sure that batch does not go into recursion. All your conditions should be properly written in finish method, and don't add an else clause in finish method.
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
add a comment |
You can use the chaining mechanism i.e. you can call your same batch class from finish method but with different parameters which you can pass via constructor of batch class. In this way, you can mention which methods needs to be called in that specific run.
For this, you can have your entire code of data factory in execute method of batch class, just that you will have to segregate your methods so that it will execute only few methods at a time i.e. whichever is passed as parameter.
Sample batch class would look like this
global class CreateSampleData implements Database.Batchable<sObject>, Database.Stateful
String runChunk;
global CreateSampleData(String strRunFor)
runChunk = strRunFor;
global Database.QueryLocator start(Database.BatchableContext BC)
return Database.getQueryLocator([SELECT Id, Name FROM Organization]);
global void execute(Database.BatchableContext BC, List<sObject> scope)
if(runChunk=='First Chunk')
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
else if (runChunk=='Second Chunk')
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
else if (runChunk=='Third Chunk')
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
else if(runChunk=='Fourth Chunk')
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
global void finish(Database.BatchableContext BC)
if(runChunk=='First Chunk')
runChunk = 'Second Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Second Chunk')
runChunk = 'Third Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Third Chunk')
runChunk = 'Fourth Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
You can call this batch class from anonymous window with single line
Database.executeBatch(new CreateSampleData('First Chunk'));
Note : You can have meaningful names for all the chunks, you will have to make that respective changes in the code as well. Also, you can segregate the chunks to have data factory methods according to the volume of data each method is creating.
Also, make sure that batch does not go into recursion. All your conditions should be properly written in finish method, and don't add an else clause in finish method.
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
add a comment |
You can use the chaining mechanism i.e. you can call your same batch class from finish method but with different parameters which you can pass via constructor of batch class. In this way, you can mention which methods needs to be called in that specific run.
For this, you can have your entire code of data factory in execute method of batch class, just that you will have to segregate your methods so that it will execute only few methods at a time i.e. whichever is passed as parameter.
Sample batch class would look like this
global class CreateSampleData implements Database.Batchable<sObject>, Database.Stateful
String runChunk;
global CreateSampleData(String strRunFor)
runChunk = strRunFor;
global Database.QueryLocator start(Database.BatchableContext BC)
return Database.getQueryLocator([SELECT Id, Name FROM Organization]);
global void execute(Database.BatchableContext BC, List<sObject> scope)
if(runChunk=='First Chunk')
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
else if (runChunk=='Second Chunk')
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
else if (runChunk=='Third Chunk')
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
else if(runChunk=='Fourth Chunk')
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
global void finish(Database.BatchableContext BC)
if(runChunk=='First Chunk')
runChunk = 'Second Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Second Chunk')
runChunk = 'Third Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Third Chunk')
runChunk = 'Fourth Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
You can call this batch class from anonymous window with single line
Database.executeBatch(new CreateSampleData('First Chunk'));
Note : You can have meaningful names for all the chunks, you will have to make that respective changes in the code as well. Also, you can segregate the chunks to have data factory methods according to the volume of data each method is creating.
Also, make sure that batch does not go into recursion. All your conditions should be properly written in finish method, and don't add an else clause in finish method.
You can use the chaining mechanism i.e. you can call your same batch class from finish method but with different parameters which you can pass via constructor of batch class. In this way, you can mention which methods needs to be called in that specific run.
For this, you can have your entire code of data factory in execute method of batch class, just that you will have to segregate your methods so that it will execute only few methods at a time i.e. whichever is passed as parameter.
Sample batch class would look like this
global class CreateSampleData implements Database.Batchable<sObject>, Database.Stateful
String runChunk;
global CreateSampleData(String strRunFor)
runChunk = strRunFor;
global Database.QueryLocator start(Database.BatchableContext BC)
return Database.getQueryLocator([SELECT Id, Name FROM Organization]);
global void execute(Database.BatchableContext BC, List<sObject> scope)
if(runChunk=='First Chunk')
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
else if (runChunk=='Second Chunk')
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
else if (runChunk=='Third Chunk')
StarWarsTestDataUtil.createCampaignHierarchy();
StarWarsTestDataUtil.individualsInsert();
StarWarsTestDataUtil.majorDonationInsert();
StarWarsTestDataUtil.mediumDonationInsert();
StarWarsTestDataUtil.smallDonationInsert();
else if(runChunk=='Fourth Chunk')
StarWarsTestDataUtil.regionaldonoraccounts();
StarWarsTestDataUtil.corporateFeesInsert();
StarWarsTestDataUtil.grantsInsert();
global void finish(Database.BatchableContext BC)
if(runChunk=='First Chunk')
runChunk = 'Second Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Second Chunk')
runChunk = 'Third Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
else if(runChunk=='Third Chunk')
runChunk = 'Fourth Chunk';
Database.executeBatch(new CreateSampleData(runChunk));
You can call this batch class from anonymous window with single line
Database.executeBatch(new CreateSampleData('First Chunk'));
Note : You can have meaningful names for all the chunks, you will have to make that respective changes in the code as well. Also, you can segregate the chunks to have data factory methods according to the volume of data each method is creating.
Also, make sure that batch does not go into recursion. All your conditions should be properly written in finish method, and don't add an else clause in finish method.
edited 3 hours ago
answered 4 hours ago
Vijay GanjiVijay Ganji
2,5052315
2,5052315
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
add a comment |
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
Thank you!!! That was perfect--literally cut and paste!
– Michael Kolodner
1 hour ago
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
If I can beg your help, anything wrong with this test code:
– Michael Kolodner
just now
add a comment |
It's certainly possible, but I wouldn't qualify it as easy. The way I would do it is to write a SandboxPostCopy script that enqueued a batch class.
This seems like a good spot to use the relatively rare batch class that iterates over a primitive or enumerated type, rather than an sObject query. The execute() method can then look at the current entity with a switch on statement and decide which batch of methods to call. I think the skeleton would look like this, and I'm cribbing some of the structure from the Nonprofit Success Pack's telemetry batches:
// define an enum somewhere
public enum PostCopyStep
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// and so on
Then, the batch class looks kind of like this, allowing it to iterate over a list of post copy steps in units of one and execute each in a separate transaction.
public without sharing class PostcopySandboxPopulationbBatch implements Database.Batchable<PostCopyStep>
private static final List<PostCopyStep> postCopySteps = new List<PostCopyStep>
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// etc.
;
public Iterable<PostCopyStep> start(Database.BatchableContext bc)
if (!Test.isRunningTest())
return postCopySteps;
else
return new List<PostCopyStep>JediStudents; // can't run multiple batches in a test.
public void execute(Database.BatchableContext bc, List<PostCopyStep> step)
switch on (step[0])
when JediStudents
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
when StarWarsPrograms
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
// etc.
public void finish(Database.BatchableContext bc)
Your post copy class would run the batch using a batch size of 1.
The additional trick is that you'll have to write test classes to validate the batch class before you can deploy it to production, and because there are so many logical branches involved it may be rather tedious. This is a place where I'd generally just call the execute() method directly in a test class (supplying each enum value in sequence) rather than trying to actually enqueue the batch.
Another approach to this is to use aninterface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.
– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
add a comment |
It's certainly possible, but I wouldn't qualify it as easy. The way I would do it is to write a SandboxPostCopy script that enqueued a batch class.
This seems like a good spot to use the relatively rare batch class that iterates over a primitive or enumerated type, rather than an sObject query. The execute() method can then look at the current entity with a switch on statement and decide which batch of methods to call. I think the skeleton would look like this, and I'm cribbing some of the structure from the Nonprofit Success Pack's telemetry batches:
// define an enum somewhere
public enum PostCopyStep
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// and so on
Then, the batch class looks kind of like this, allowing it to iterate over a list of post copy steps in units of one and execute each in a separate transaction.
public without sharing class PostcopySandboxPopulationbBatch implements Database.Batchable<PostCopyStep>
private static final List<PostCopyStep> postCopySteps = new List<PostCopyStep>
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// etc.
;
public Iterable<PostCopyStep> start(Database.BatchableContext bc)
if (!Test.isRunningTest())
return postCopySteps;
else
return new List<PostCopyStep>JediStudents; // can't run multiple batches in a test.
public void execute(Database.BatchableContext bc, List<PostCopyStep> step)
switch on (step[0])
when JediStudents
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
when StarWarsPrograms
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
// etc.
public void finish(Database.BatchableContext bc)
Your post copy class would run the batch using a batch size of 1.
The additional trick is that you'll have to write test classes to validate the batch class before you can deploy it to production, and because there are so many logical branches involved it may be rather tedious. This is a place where I'd generally just call the execute() method directly in a test class (supplying each enum value in sequence) rather than trying to actually enqueue the batch.
Another approach to this is to use aninterface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.
– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
add a comment |
It's certainly possible, but I wouldn't qualify it as easy. The way I would do it is to write a SandboxPostCopy script that enqueued a batch class.
This seems like a good spot to use the relatively rare batch class that iterates over a primitive or enumerated type, rather than an sObject query. The execute() method can then look at the current entity with a switch on statement and decide which batch of methods to call. I think the skeleton would look like this, and I'm cribbing some of the structure from the Nonprofit Success Pack's telemetry batches:
// define an enum somewhere
public enum PostCopyStep
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// and so on
Then, the batch class looks kind of like this, allowing it to iterate over a list of post copy steps in units of one and execute each in a separate transaction.
public without sharing class PostcopySandboxPopulationbBatch implements Database.Batchable<PostCopyStep>
private static final List<PostCopyStep> postCopySteps = new List<PostCopyStep>
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// etc.
;
public Iterable<PostCopyStep> start(Database.BatchableContext bc)
if (!Test.isRunningTest())
return postCopySteps;
else
return new List<PostCopyStep>JediStudents; // can't run multiple batches in a test.
public void execute(Database.BatchableContext bc, List<PostCopyStep> step)
switch on (step[0])
when JediStudents
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
when StarWarsPrograms
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
// etc.
public void finish(Database.BatchableContext bc)
Your post copy class would run the batch using a batch size of 1.
The additional trick is that you'll have to write test classes to validate the batch class before you can deploy it to production, and because there are so many logical branches involved it may be rather tedious. This is a place where I'd generally just call the execute() method directly in a test class (supplying each enum value in sequence) rather than trying to actually enqueue the batch.
It's certainly possible, but I wouldn't qualify it as easy. The way I would do it is to write a SandboxPostCopy script that enqueued a batch class.
This seems like a good spot to use the relatively rare batch class that iterates over a primitive or enumerated type, rather than an sObject query. The execute() method can then look at the current entity with a switch on statement and decide which batch of methods to call. I think the skeleton would look like this, and I'm cribbing some of the structure from the Nonprofit Success Pack's telemetry batches:
// define an enum somewhere
public enum PostCopyStep
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// and so on
Then, the batch class looks kind of like this, allowing it to iterate over a list of post copy steps in units of one and execute each in a separate transaction.
public without sharing class PostcopySandboxPopulationbBatch implements Database.Batchable<PostCopyStep>
private static final List<PostCopyStep> postCopySteps = new List<PostCopyStep>
JediStudents,
StarWarsPrograms,
CampaignHierarchy,
// etc.
;
public Iterable<PostCopyStep> start(Database.BatchableContext bc)
if (!Test.isRunningTest())
return postCopySteps;
else
return new List<PostCopyStep>JediStudents; // can't run multiple batches in a test.
public void execute(Database.BatchableContext bc, List<PostCopyStep> step)
switch on (step[0])
when JediStudents
StarWarsTestDataUtil.createJediStudents();
StarWarsTestDataUtil.createStarWarsCompaniesWithMentors();
StarWarsTestDataUtil.createStarWarsRecruitCamp();
when StarWarsPrograms
StarWarsTestDataUtil.createStarWarsPrograms();
StarWarsTestDataUtil.putMentorsOnCampaign();
StarWarsTestDataUtil.putStudentsOnCampaign();
StarWarsTestDataUtil.putProgramOnCatEnts();
StarWarsTestDataUtil.putMentorships();
StarWarsTestDataUtil.createRegionSchools();
// etc.
public void finish(Database.BatchableContext bc)
Your post copy class would run the batch using a batch size of 1.
The additional trick is that you'll have to write test classes to validate the batch class before you can deploy it to production, and because there are so many logical branches involved it may be rather tedious. This is a place where I'd generally just call the execute() method directly in a test class (supplying each enum value in sequence) rather than trying to actually enqueue the batch.
answered 6 hours ago
David Reed♦David Reed
42.1k82463
42.1k82463
Another approach to this is to use aninterface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.
– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
add a comment |
Another approach to this is to use aninterface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.
– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
Another approach to this is to use an
interface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.– sfdcfox
2 hours ago
Another approach to this is to use an
interface, then you'd have a list of classes that you could instantiate and run. This is pretty close to what we plan on implementing in our own org.– sfdcfox
2 hours ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
Given the problems I've had with SandboxPostCopy (it runs in a context that doesn't have privilege to insert), I think I'll stick with running in Execute Anonymous...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
But could you point me to more information on using an interface? Sounds intriguing, even if it might be beyond my skill level...
– Michael Kolodner
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
@MichaelKolodner You could also enqueue the batch class via Anonymous Apex if desired.
– David Reed♦
1 hour ago
add a comment |
Take the basic structure of a batch class: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Start, execute, finish.
Then chain the batches together. So batch 1 would execute be two or 3 methods and then finish would point to batch 2, which would execute 2 or 3 methods depending on how big they are. And so on and so on till you've got them all.
add a comment |
Take the basic structure of a batch class: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Start, execute, finish.
Then chain the batches together. So batch 1 would execute be two or 3 methods and then finish would point to batch 2, which would execute 2 or 3 methods depending on how big they are. And so on and so on till you've got them all.
add a comment |
Take the basic structure of a batch class: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Start, execute, finish.
Then chain the batches together. So batch 1 would execute be two or 3 methods and then finish would point to batch 2, which would execute 2 or 3 methods depending on how big they are. And so on and so on till you've got them all.
Take the basic structure of a batch class: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
Start, execute, finish.
Then chain the batches together. So batch 1 would execute be two or 3 methods and then finish would point to batch 2, which would execute 2 or 3 methods depending on how big they are. And so on and so on till you've got them all.
answered 6 hours ago
Dan WoodingDan Wooding
2,0131539
2,0131539
add a comment |
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f262339%2fmake-a-class-to-batch-an-existing-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
alternative: consider vendor product: Gearset
– cropredy
2 hours ago