7

Is it possible to use a database query to get a set of related records and clone them into new related records.

sObject[] sObjectsWithChildRelationships = [SELECT Id, (SELECT Id, myObject__c FROM name_of_relationship__r) FROM myObject__c];
sObject[] cloneOfsObjectsWithChildRelationships = sObjectsWithChildRelationships.deepClone(false,false,false);

I'm trying to get the look-up relationship on name_of_relationship__r records to be duplicated into a new matching set of parent records, in this case myObject__c

2
  • Hi Jordan, what problem are you trying to solve here?
    – Benj
    Commented Aug 10, 2012 at 18:41
  • I'm trying to clone a set of records AND the records that have look-ups that map to those records. Commented Aug 10, 2012 at 19:44

6 Answers 6

4

I may not understand the questions, but I wrote a blog post a while ago about cloning records. See http://sfdc.arrowpointe.com/2011/03/28/cloning-records-in-apex/. It may help. It basically has a method that will build you a SOQL query that contains all the writable fields. You'd need to make that query and then do a .clone() on the sObject in Apex and then make whatever changes you need, then insert it.

2
  • hey @hemmeter, I actually looked at your blog post, and I get what your saying about querying all the fields. However, my issue was with cloning sObject's and having their children (look-up relationship) be cloned as well. Like: sObject[] parentObjectsWithChildren = [SELECT Id, (SELECT Id FROM RelationshipName__c) FROM Parent__c)]; sObject clones = parentObjectsWithChildren.deepClone(false,false,false); The new cloned sObjects don't have cloned children with them. Commented Aug 14, 2012 at 19:09
  • Ah ha! I get it now. Hmm. Well, I know you can include a record and it's children using SOQL relationships, but am not sure about limits. A single SOQL statement is capable of getting, say, an Account and its related Contact/Opportunities/Cases/etc.
    – hemmeter
    Commented Aug 14, 2012 at 22:59
6

Why would going one by one mean running out of queries? You could grab them all, clone them into a list and update the list in groups of 200.

If doing that is still likely to present problems then I think the best way forward is for you to write a class implementing the Batchable interface, they're designed explicitly to do heavy data lifting like this!

1
  • I guess your right. The issue than becomes why don't the relationship records get cloned with the list of parent objects that get returned? Commented Aug 10, 2012 at 18:04
2

The free Astrea Clone app only works with Standard Objects.

There is another App called Object Converter which can be used to clone Parent & Children for both standard and custom objects

1
  • Your comment on Astrea Clone is lacking context; please either reference the other answer or post that as a comment to the other answer.
    – Mike Chale
    Commented Dec 3, 2012 at 11:58
2

Unfortunatly you cannot set in memory the relationship fields, so cannot reproduce the relationships in memory you can obtain by using inner queries for child or relatated records in SOQL, shame I agree.

What you might be interested in though is something I have recently developed and blogged about. It is a SObjectDataLoader class that has methods to serialise and deserialise SObject records including their related records. One of the use cases is to implement a deep clone (rather than the shallow one the platform provides). You can take a look at my blog article about it here.

Basically though it would allow you to do this...

Set<Id> myNewRecords = 
     SObjectDataLoader.deserialise(
         SObjectDataLoader.serailise(new Set<Id>{ myExistingRecordId });

It uses JSON internally as the format, wrapped in an Apex custom class to maintain the relationships and insertion order of the serialised records. I know it actually inserts the records, so maybe not 100% what you want. Check out the full details and implementation approach on my blog article.

1

Check out this newly posted package from the AppExchange: Astrea Clone. (Note: I have no connection with the publishers).

It doesn't help with this use-case in Apex, but allows the same task to be accomplished with point-and-click.

0

I wrote a generic utility class that can help with this. With your example, the usage of it would look something like this:

Id myObjIdToClone = '00Q3A00001Q0wu7'; //My_Object__c Id
SObjectDeepClone cloner = new SObjectDeepClone(
    leadIdToClone,
    new Set<String>{
        'name_of_relationship__r'
    }
);
Id clonedMyObjId = cloner.save();

Note, it automatically copies all createable fields for the parent and children objects.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .