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;








2















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();









share|improve this question






















  • alternative: consider vendor product: Gearset

    – cropredy
    2 hours ago

















2















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();









share|improve this question






















  • alternative: consider vendor product: Gearset

    – cropredy
    2 hours ago













2












2








2








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();









share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 6 hours ago









Michael KolodnerMichael Kolodner

847




847












  • 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





alternative: consider vendor product: Gearset

– cropredy
2 hours ago










3 Answers
3






active

oldest

votes


















1














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.






share|improve this answer

























  • 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


















3














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.






share|improve this answer























  • 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











  • 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


















2














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.






share|improve this answer























    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
    );



    );













    draft saved

    draft discarded


















    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









    1














    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.






    share|improve this answer

























    • 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















    1














    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.






    share|improve this answer

























    • 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













    1












    1








    1







    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.






    share|improve this answer















    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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

















    • 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













    3














    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.






    share|improve this answer























    • 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











    • 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















    3














    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.






    share|improve this answer























    • 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











    • 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













    3












    3








    3







    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.






    share|improve this answer













    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.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 6 hours ago









    David ReedDavid Reed

    42.1k82463




    42.1k82463












    • 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











    • 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











    • 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











    2














    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.






    share|improve this answer



























      2














      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.






      share|improve this answer

























        2












        2








        2







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 6 hours ago









        Dan WoodingDan Wooding

        2,0131539




        2,0131539



























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Siegen Nawigatsjuun

            Log på Navigationsmenu

            Log på Navigationsmenu