Wednesday 18 May 2011

How to dynamically clone Salesforce objects with all fields populated

UPDATE 25/04/2012: If cloning child objects using a custom button is of interest to you, check out my post regarding Clone Plus!!!  

There are several scenarios during development where it becomes necessary to create complete copies of instances of Salesforce objects. Salesforce already provides a generic "clone" method to copy objects by casting them first to a more primitive base sObject. The clone method for sObjects even has a parameter which re-creates all relationships opt_IsDeepClone. The documentation describes that turning this option to true will result in a full copy of the sObject being returned by the method.

However, a common problem developers have when using this method is that it does not automatically copy all of the objects field values from the database. Instead, the opt_IsDeepClone option only copies the field values currently held in memory that have been retrieved through use of a SOQL query or have been populated directly in the Apex code. 

It is well known that Salesforce does not provide a "SELECT * FROM" method, so creating a cloning method that is guaranteed to copy all fields, and maintaining that functionality if any modifications are later made to the object, is challenging.

The way to accomplish a complete clone including all field values is to make use of the schema object definitions, which are accessible through apex code. You can use these definitions to retrieve all the fields for a particular object. These field name strings can be concatenated into a SOQL query to ensure all values are retrieved. My example code can be seen below:

public class SObjectAllFieldCloner {

  // Clone a list of objects to a particular object type
  // Parameters 
  // - List<sObject> sObjects - the list of objects to be cloned 
  // - Schema.SobjectType objectType - the type of object to be cloned.
  // The sObjects you pass in must include the ID field, 
  // and the object must exist already in the database, 
  // otherwise the method will not work.
  public static List<sObject> cloneObjects(List<sObject> sObjects,
                                        Schema.SObjectType objectType){
    // A list of IDs representing the objects to clone
    List<Id> sObjectIds = new List<Id>{};
    // A list of fields for the sObject being cloned
    List<String> sObjectFields = new List<String>{};
    // A list of new cloned sObjects
    List<sObject> clonedSObjects = new List<sObject>{};
    // Get all the fields from the selected object type using 
    // the get describe method on the object type.
    if(objectType != null){
    // If there are no objects sent into the method, 
    // then return an empty list
    if (sObjects != null && 
        !sObjects.isEmpty() && 
      // Strip down the objects to just a list of Ids.
      for (sObject objectInstance: sObjects){

      /* Using the list of sObject IDs and the object type, 
         we can construct a string based SOQL query 
         to retrieve the field values of all the objects.*/
      String allSObjectFieldsQuery = 'SELECT ' + sObjectFields.get(0); 
      for (Integer i=1 ; i < sObjectFields.size() ; i++){
        allSObjectFieldsQuery += ', ' + sObjectFields.get(i);
      allSObjectFieldsQuery += ' FROM ' + 
                               objectType.getDescribe().getName() + 
                               ' WHERE ID IN (\'' + sObjectIds.get(0) + 

      for (Integer i=1 ; i < sObjectIds.size() ; i++){
        allSObjectFieldsQuery += ', \'' + sObjectIds.get(i) + '\'';
      allSObjectFieldsQuery += ')';
        // Execute the query. For every result returned, 
        // use the clone method on the generic sObject 
        // and add to the collection of cloned objects
        for (SObject sObjectFromDatabase:
      } catch (exception e){
        // Write exception capture method 
        // relevant to your organisation. 
        // Debug message, Apex page message or 
        // generated email are all recommended options.
    // return the cloned sObject collection.
    return clonedSObjects;

An example of how you would call this method  to clone an Account object from another Apex controller is:

Account originalAccount = [select Id from Account where 
                                name = 'My Favourite Account'];

sObject originalSObject = (sObject) originalAccount;

List<sObject> originalSObjects = new List<sObject>{originalSObject};
List<sObject> clonedSObjects = SObjectAllFieldCloner.cloneObjects(
Account clonedAccount = (Account)clonedSObjects.get(0);

Notes: This query only copies a single type of object at a time, related child objects are not cloned, however all lookup relationships/master record references are copied. Also in this example, I have shown how to create a virtual "SELECT * FROM" to make this resistant to change. This type of query should only be used when absolutely necessary, never out of developer laziness.

There are a lot of combined concepts in this example; mapping objects, using object definitions and generic sObject methods amongst other. If you require any further explanation to any of the elements of this solution, please list a question below.


  1. This looks nice. However, I don't know how to execute scripts on SFDC. Do you have a way to turn this into a nice button that I can press somewhere?

  2. Hi dengeltrees. In terms of buttons, standard Salesforce object summary pages have "clone" buttons by default which can be used to create a carbon copy of an existing object easily. The scripts I provide here are for custom processes where an object needs to be cloned as part of an Apex process.

    If you have a particular scenario that you want to use this functionality in, or want to place a button for this functionality inside a visualforce page, reply on this thread or send me an email and I would be happy to point you in the right direction and provide a specific example.

    1. I want to clone an Account record and after cloning the Account I want to change a particular fields value. Please help me in achieving it. My email id is

    2. Hi Puki,

      In terms of the values you want to set in the fields, are they constant values, or are these values you want to manually edit after cloning the record?


  3. Useful post Christopher. I thought it was worth adding that there is a limit on the query size for SOQL of 12000 characters - so if there are 100s of custom fields and you try to query them all then this limit can be hit

    1. Thanks HO1D3R! that is worth a mention, if the object you are trying to clone is very large then this limit may be hit.

  4. Hi Christopher,
    Our team uses a custom object that is parent to another custom object. I'd like to be able to have a Clone button on the parent object which acts like the standard 'Clone w/Products' button, but clones the linked children objects along with my parent custom object. I'm not a coder at all and unfortunately we've got no development budget at the moment, so I'm hoping you might know of a quick solution that involves some free code being copied into a custom button, which I may be able to figure out.

    1. Hi James. Unfortunately I'm not sure I can make quick generic object code that will achieve the above through a button on the summary object page. It is possible to create a button that links to a custom page that clones the object and its children and then directs you to a summary page of the cloned object.

      If you email me a few more details about your objects and their relationships, I may be able to adapt the above code to your requirements.

    2. Did you arrive at any solution for this challenge?


    3. Since there has been a few comments regarding this, I took another look at how to turn this into a more directly useful example, which involves a custom button.

      I have finished the prototype, which I am in the process of testing. You should see a follow up post shortly!

    4. Were you ever able to accomplish this in a custom button? Specifically, I'm trying to clone an opportunity and retain the original owner of the cloned opportunity.

    5. Hi Waltee, I did manage to accomplish this through a custom button, and you can too! Follow the link at the top of the page entitled "clone plus". This will provide you with a step by step guide on how to allow cloning of your objects whilst creating copies of any required child objects too.

      Any questions let me know,


  5. i have created three custom objects on my opportunity records. i would like, when i select the CLONE button on the opportunity, to be able to say, clone opp with 1 or all 3 of these custom objects. how can i adjust the existing CLONE button to accomplish this, or how can i make a custom button to accomplish this task?

    1. Hello Blake. My recommendation would be to create a custom visualforce page with a controller that is based on the above code. The method could be used to clone the original opportunity, then clone all the objects that have a master detail/lookup relation to the original opportunity, retrieving these using SOQL.

      The relationship to the new object can be defined by populating the master detail/lookup field with the Id of the new cloned opportunity.

      In terms of replacing the original clone button, you can create a custom clone button through the buttons and links menu (App Setup --> Customize--> Opportunities --> Buttons and Links) that links directly to the visualforce page specified above.

      I hope that helps, feel free to ask for further explanation if anything is unclear.

  6. Hi Christopher,

    I'm eager to see what you have prototyped as a custom button to implement the clone functionality. I need to deploy a solution to clone a child record to a new parent and the child record contains a unique ID, the implementing the standard clone functionality is awkward for an end user at best.


    1. Hi Datagirl,

      Thanks for getting in touch, I do plan on making a post this weekend containing the new prototype I have developed. It is driven from a custom button and will have the facility to clone a record and edit the details before saving. I see it as being very useful for those situations where a master detail child record needs to be copied.

  7. Hi,

    Please could you help. Having no programming skills, I am unsure of whether this has already been answered.

    I would like to replicate the 'campaigns' tab and objects and use the new one to keep track of certain things separate to a campaign.

    Is it possible to duplicate a tab and objects related to it?



    1. Hello Abby (or Craig :S)

      Your question is a little confusing, but I think what you may be after if you want to store additional information unrelated to a campaign is a custom object.

      A custom object (and related tab) can be created simply through the Salesforce setup menu.

      I think you should check out the following workbook, it shows you step by step how to create objects and tabs.

      If I have misunderstood and this is not what you are after, please let me know.



  8. This is great thanks! How about cloning to another custom object?

    So Object_a__c I would clone to object_b__c (with the fields being dynamically created on object_b__c).

    Is what I am asking even possible?

    1. Hi Anthony,

      I'm not sure how easy it is to create fields dynamically on an object. This does seem like quite an unusual request, can you possibly explain how this situation has come about, or provide a little more information about why you what to do this?

      I'm inclined to think there may be an easier way to alter your objects to a required specification rather than writing dynamic field code.

    2. Hi Christopher, thanks for the response and sure.

      I was trying to make an object that contains a copy of another.

      So let’s say I have a Lead (or any object really). I want to copy that Lead to my custom object where I would have access to all the fields’ data (not just formulas fields). That way I can manipulate the actual data without modifying the original Lead. Moreover, I may export to an external system and that system may manipulate the data.

      Once I am done with the Lead, I would send it back to the original Lead overwriting the data values. I could do this manually by copying the Lead record and by matching all the fields (in fact I already have done this). But I wanted to get something a little more dynamic.

      So, if a user adds a field to the Lead object I need to go in and add the mapping to my APEX code and add the field to my object.

      I was thinking I could clone from one to the other. Would you suggest another route?

      Thanks so much for you input!


    3. Ah I see, thanks for the further explanation Anthony.

      A dynamic copy between objects is acheivable by extending some of the features outlined in the cloning method described above.

      To start with, get both object field maps using the object type describe methods. Use the lead field map and SOQL to populate all the lead object fields, as in the clone method.

      Then, using the two object field map SObjectField value sets, create two new maps that map from field label to field API name. This is necessary as the dynamic mapping has to be based on field label, not field API name.

      If we mapped on the field API names, the copy process could not map the fields, as custom object fields always end in __c, standard object fields do not.

      Finally by itering through the lead field names map like in the follow psuedo code, you will copy the fields between the objects. Make use of the get(FieldAPIName) and put(FieldAPIName) common sObject methods to retrieve the field values from the lead and place them into the custom object.

      for each (leadFieldLabel in leadFieldMap)
      customObjFieldAPIName = customObjFieldMap.get(leadFieldLabel)

      if (customObjFieldAPIName != null)
      fieldValue = lead.get(leadFieldMap.get(leadFieldLabel))

      customObject.put(customObjFieldAPIName, fieldValue)

      I hope that helps!

      If you need any further help or further explanation, let me know.

  9. Hi Christopher -

    I came across your page because I have the following issue and figured it was worth a shot to ask and see if you had any ideas:

    I have a custom object, and the view and edit pages have been overridden. The edit page uses a standard controller, with an extension. On the view page, I want there to be a clone button. The standard clone won't work because I need the edit page to be overridden with my fancy-schmancy one. Therefore, I've overridden the clone page as well, to point to my edit page.

    I'm also using field sets to control which fields are visible on the pages.

    When you click "clone" on my view page, it calls a controller action which returns a reference to /[objectid]/e?clone=1 ... which brings you to my edit page. However, it is not in "clone" mode. It's in "edit" mode. So, if I save, it just updates the existing record.

    So, I was thinking that rather than use the standard controller, I'd just query the record myself, and use that particular record to populate the data on the VF page. That way, If I see the "clone=1" in the URL I can just call the clone(false) method on that record, and get a fresh clone that is ready to be changed and saved with a new Id.

    The issue is with the field sets. Because new fields can be added to it, and therefore added to the VF page, the query that gathers the data needs to be dynamic. This is where your nifty little hint using Schema methods comes in.

    I was just wondering if you could think of any way that was less challenging. It seems like a lot of work for functionality that is standard to SF.

    Thanks for the time.

    Morgan Henris

    1. Hello Morgan,

      It seems you are not the only one who is experiencing the problem with overriding the clone button, check out this page I found from the forums:

      In terms of the cloning method only copying what is in your field set at a given time, this is entirely possible. The following field sets documentation shows how to get all of the fields and values for a field set using Apex (check out the example under "Working with Field Sets Using Apex":

      Using this in combination with the clone(false) method, you should be able to clone just the fields you want.

      Let me know how you get on!

      Christopher Alun Lewis

  10. Hi Christopher! Awesome page you have here. I have a question.

    I would like to have a custom object that is a duplicate of a created Case, that can be edited on both sides and have real time integration. So when a case is created, the team actually will work on the custom object that has the preliminary Case info on it. It will then save and have the case workflows escalate.

    This is because I would like to utilize the Chatter Plus licenses in the client support section.

    Could I get your help with this? Thanks.

    Nick Winch

    1. Hi Nick,

      In terms of creating this kind of real time integration, it would be essentially possible using a series of triggers on both objects in conjunction with a cloning function like the example above. The triggers would have to cover every single DML operation (insert, delete, update, upsert, undelete). You would have to be mindful of infinite loops though, so that object A does not create object B which then creates another object A and so on....

      However, I would really consider why you are using chatter plus licences in this way. By keeping lightweight licences you are preventing the users from using all the extra features included with cases as standard and creating a potentially unreliable maintainance overhead.

      Without these extra features, the case object inside Salesforce is just a data structure, which is why there is a cost associated with using it. If you do not want to use the special features such as case workflows, then I would recommend modelling your entire support desk using custom objects. I think it is bad practice (especially in terms of storage) to have two copies of all data.

      For a more lightweight support model, you may want to consider using, a Salesforce support product that is much more adaptable, and may be more suited to your situation.

      I hope that helps.

  11. Hi Christopher,
    This post is just so awesome!
    Thank you for posting it.

    I've a problem understanding the line :
    if (sObjects != null ||
    sObjects.isEmpty() ||

    Can you explain the condition?
    I'm sorry if its obvious but I'm still a noob.

    1. Hi Puneet,

      Thanks! The purpose of the condition is to catch any obvious scenarios where the arguments passed to the method will either cause an exception or not produce any worthwhile results.

      The first two conditions basically check that the list of sObjects argument passed into the method has actually been populated with a valid list object (not null), and that it actually contains some objects to clone in it (not empty).

      The final condition checks that fields for the sObject type have been successfully retrieved by examining the object type map.

      If any of these conditions fail, then there is no point attempting to generate clones. Looking back at this, you might argue it would be better to throw an exception if any of those conditions occur, rather than just not doing some code if it occurs.

      Hope that helps, let me know if you need any more info!


    2. Hi Christopher,

      Thanks for the reply.
      What I was thinking is that if I pass something like.

      List clonedSObjects = SObjectAllFieldCloner.cloneObjects(null, null);


      List clonedSObjects = SObjectAllFieldCloner.cloneObjects(null,

      The above condition will cause exception because null.isEmpty() is not valid.

      So, it would be better to check for
      if (sObjects != null)
      first and then in inner if condition you may check

      Does that make sense?


    3. Hi again Puneet,

      Yeah that does make sense. Following your query I have reviewed the if condition again, and its actually not doing the job it was supposed to. The statement

      if (sObjects != null || SObjects.isEmpty() || sObjectFields.isEmpty())

      will enter the logical statement if sObjects collection is not null or the sObjects collection is empty or if the sobjectFields collection is empty. This is wrong, the whole point was to make sure that an empty list is never processed, but this condition states that is ok. Why would we want to process an empty list?

      The conditional statement should actually look like this:
      if (sObjects != null && !SObjects.isEmpty() && !sObjectFields.isEmpty())

      This new statement actually now reads, if the collection of sobjects is not null and is not empty and the list of sobject fields is not empty, proceed! So empty lists will not be processed

      I'm sorry if you were trying to point this out in your first post, the penny only just dropped when I had another look at it. I'm going to take this as a lesson in the importance of test methods covering all possibilities :)

      With regards to your reply, you are correct that you should always check that a collection is null before checking that it is empty. However both checks can be done in the same conditional statement. If the collection is null, the first conditional logic section will fail and return false before the "isEmpty()" statemnt is evaluated.

      I have updated the code above with the corrected conditional statement.

      Thanks very much for the comments


    4. Hi Christopher,

      Yep. That's it!
      Sorry if I wasn't clear in my first post. I'm bad at that.
      Anyway that looks good and once again thank you very much for this code. I'm using your dynamic query for entirely different purpose.


    5. No worries Puneet! Glad to help and thanks again for identifying the condition problem, good to know people actually sense check what they are copying :)



  12. This comment has been removed by the author.

  13. How to clone multiple opportunities at a time from List view?

    1. Hi Kanth,

      Hmm. As an idea to do this, you could need to first create a new custom list button that executes javascript when clicked. The javascript would need to retrieve all of the records that a user selects from the list view, and then send the selected record ids inside a url variable as part of a redirection a Visualforce page.

      From the Visualforce page, you could use a custom controller to interrogate the URL, and retrieve the record Ids. From there, initialise some opportunity objects with the ids, and use the "cloneObjects" method above to copy them.

      That is how I would approach the problem at first, let me know if that helps and how you get on!


  14. Thanks so much. This is a lifesaver! I just tested this in my Sandbox and it works great. I'm going to setup a trigger to clone cases.

    How would recommend filtering what fields that I may not want? What I'm doing now is setting the values of the fields I don't want with values manually after calling the method. For instance I have flag that my trigger would check to fire the clone, so I would need to set that back to false afterward. Ideally, if I could filter that field and others that would be great.

    1. Hi Andrew,

      Good question! There are a number of ways to do this I can think of off the top of my head. The simplest way to do this is to remove the these filtered fields directly in the controller depending on the object as part of the clone method, i.e. if record type = x then clone all fields except y, z etc. You can store this configuration in an inner class or controller variables.

      But of course this is a bit clumsy, and takes away some of the generic nature of the method. Every time that you want to change the fields or include a new object, you have to update the code (and associated tests). If you are still keen to maintain this, I recommend you have a look at field sets: ( You could define a field set on each object that represents the fields that you want to filter out (or conversely that you want to include in the clone), and call it "cloneplusfields" for example. Then in your controller code, when constructing the SOQL query to retrieve the object details, simply reference the field set (SObjectType.Merchandise__c.FieldSets.cloneplusfields.getFields() etc.), and use the returned results to filter out the fields you don't want. This way, you can even manage the filtered fields using clicks :)

      Alternatively, you could use custom settings instead of field sets to achieve similar results.

      Hope that helps, let me know how things go!


  15. Hi Christopher Alun Lewis,
    one page i displayed all fields using schema methods(here object name through URL will come like string strtemp = 'rajesh__'+strFieldName + '__c'; )and wrapper class. using wrapper class i gave each field as Edit and Delete command links .When i click delete command link how to delete that delete command link related field from database.

    Another visualforce page i displayed all Custom objects using schema methods and wrapper class. Using wrapper class i gave each Custom object as Edit and Delete command link .When i click delete command link how to delete that delete command link related object from database.

    please help me......

    1. Hello K mahesh,

      This all seems to be quite complicated. From what I understand, you want to show all the field values for an object, then have edit and delete links next to each indiviudal field. If this is coorect, I would recommend just using a standard page layout. Always use out the box functionality when able.

      Similarly, if you are trying to manage objects and fields via a custom Visualforce interface, again I would question the value, the standard menu is very capable of managing custom objects and fields.

      Hope that helps,

  16. Hi sir,
    I have one requirement,
    Actually using below code i save object record in database dynamically.
    Schema.SObjectType targetType = Schema.getGlobalDescribe().get(strFieldName);
    SObject myObj = targetType.newSObject();
    insert myObj;

    Note:using above code related object record only created.

    but I gave some fields information here but those fields information is not saved in this record
    How to save fields information also related object record Dynamically?

    Note:Here my object fields add dynamically

    help me......

    1. Hi k mahesh,

      Again I would question the value of what you are tyring to acheive, what is the purpose of this page?


  17. I have a requirement wherein i have to copy the record with its child objects. Have created a custom clone button.

    I have to ignore some of the child records based on some condition.

    Suppose the Parent Object is TestAcc and child Object is TestProj. TestAcc has 3 TestProjects associated with it. I want to ignore the TestProject record where the ProjectManager is same as logged in User.

    public void testclone(String dId, List childRecords, String query) {

    for(ChildRelationship child : childRecords) {
    List existingRecords = Database.query(query);
    List newRecords = existingRecords.deepClone(false);

    for(SObject obj : newRecords) {
    obj.put(child.getFieldName(), dId);

    Database.SaveResult[] newData = Database.Insert(newRecords, true);//Insert newly cloned records



    1. Hi Neha,

      Sorry I don't quite understand, do you have a question or want some advice on how to accomplish your requirement. Or possibly review your testing code.

      Please let me know.

  18. hi CAL,
    i have a requirement to clone a custom and standard object which has look up relation to the custom object . is this possible .

  19. How to track more than 20 fields without writing trigger and without creating sobject in salesforce ?

  20. Hi Christopher, very informative post! I came across it while looking for a way to kick the cloning. We have the cloning code in an apex class and were using a trigger to clone the records when an event happened, I have been instructions to delete the trigger and call the Clone method from the apex class , into a batch class. When the batch job runs, along with other things it should also do a deep clone of the original record. I have been trying this by calling the method from the batch class but it doesnt clone. Even if I copy the whole cloning code in the batch class, it still does not clone when the job runs.
    Do you think its possible to achieve cloning, from a batch job?


  21. Hi Christopher, Are the fields such as required fields, non editable fields, look up fields, summary fields are covered by the code? Thanks.

  22. Is there any way to select related list which you want to clone while cloning the parent record?

  23. thanks for posting such an useful and informative stuff.....

    Salesforce Online Training

  24. Hi, this code is amazing help me a lot, i have a question i want a clone with a few fields from my object its possible do that


  25. I am truly inspired by this online journal! Extremely clear clarification of issues is given and it is open to every living soul. I have perused your post, truly you have given this extraordinary informative data about it.
    Tinder Clone

  26. Ms. Garth is married to William H. Hicks, executive director of the Southside and Dodson Avenue Community Health Centers (affiliated with the Erlanger Health System) and is the mother of Rachel Aurelia and Sarah Elizabeth Hicks. Drugs called mitotic inhibitors stop cancer cells from making more copies of themselves. They can also stop your body from making the proteins that cancer cells need to grow. Doctors might prescribe them for breast and lung cancers and types of myeloma, leukemia, and lymphoma.

    So the young woman Coach Outlet Online who aspired to be a chef met Best Yeezys Andrea Coach Outlet Clearance Sale J. Green, 25, and Deneilo R. Bradshaw, 23, on May 7 to buy 1,500 MK Outlet Online ecstasy pills, 2 ounces of cocaine Nike Air Force 1 Cheap Outlet or crack, and a Jordan Shoes For Sale gun. A handy eye Cheap Michael Kors Handbags shield sets this Ray Ban Outlet helmet apart from the otherwise nearly identical Giro Air Attack. The magnetically fastened eye shield promotes total eye protection. You can easily remove the shield if desired..

  27. I like your all post. You have done really good work. Thank you for the information you provide, it helped me a lot. I hope to have many more entries or so from you.
    Very interesting blog.

    Carbon Copy Cloner Crack

    Disk Drill Pro Crack

    Bartender Crack