function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
PlatFormCloudPlatFormCloud 

Clone and DeepClone

Hi Experts,
What is the difference between Clone () and DeepClone() in Apex? When should we use what? Can someone explain with an example?

Thanks!
Best Answer chosen by PlatFormCloud
BALAJI CHBALAJI CH
Hi PlatFormCloud,

Here is a Small Example to Understand difference between them:

I am just inserting a New Account with some fields.
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;
This creates a record in the Account as shown below:
User-added image

Now, I am cloning it and inserting again.
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;    

//Cloning the above Account Record ac
Account acCloneCopy  = ac.clone(false, false, false, false);
insert acCloneCopy;
It creates a new copy of the record with same values, since it keeps the reference, new record ID is generated for cloned record.
User-added image

Now, when I try to deepclone the record:
(Deepclone is done by keeping tru in the parameters: Syntax - clone(preserveId, isDeepClone, preserveReadonlyTimestamps, preserveAutonumber))
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;    

//Deep cloning the above record
Account acCloneCopy  = ac.clone(true, true, false, false);
insert acCloneCopy;
It shows an error, because the Id is also considered and cannot insert the deppcloned record:
User-added image

Best Regards,
BALAJI
 

All Answers

BALAJI CHBALAJI CH
Hi PlatFormCloud,

Basic difference between clone and deep clone are follows :

Clone:
  • Generally clone the list of object and keep the reference.
  • Supports primitive data type
  • Parameters are not applicable.
Deep clone:
  • Generally it clone the list of object but don't hold any reference.
  • doesn't support primitive datatype.
  • Parameter are applicable.
Please find below links for more uderstanding:
http://www.infallibletechie.com/2014/08/difference-between-clone-and-deepclone.html
https://developer.salesforce.com/forums/?id=906F0000000BH0gIAG

Let us know if that helps you.

Best Regards,
BALAJI
PlatFormCloudPlatFormCloud
I saw these answers in the blogs. But everything was not clear. What do you mean by Clone holds the refgence and DeepClone does not?
Can you please explain when should I use clone and when DeepClone?
SFDC GuestSFDC Guest
Hi,

Clone: means creating a new record with the existing details of another reord.

Here is the example:
Account acc = [SELECT Name, Type FROM Account  LIMIT 1];

Account accCopy  = acc.clone(false, false, false, false);

if you insert accCopy, it will be the exact copy of acc.

DeepClone: creating a new record with the existing details of another reord along with related lists.

Thank You.
SFDC GuestSFDC Guest
Here is the best example for DeepClone.
http://blog.jeffdouglas.com/2009/11/19/apex-deep-clone-controller/

Please mark it as best answer if it is hepled you.

Thank You.

 
BALAJI CHBALAJI CH
Hi PlatFormCloud,

Here is a Small Example to Understand difference between them:

I am just inserting a New Account with some fields.
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;
This creates a record in the Account as shown below:
User-added image

Now, I am cloning it and inserting again.
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;    

//Cloning the above Account Record ac
Account acCloneCopy  = ac.clone(false, false, false, false);
insert acCloneCopy;
It creates a new copy of the record with same values, since it keeps the reference, new record ID is generated for cloned record.
User-added image

Now, when I try to deepclone the record:
(Deepclone is done by keeping tru in the parameters: Syntax - clone(preserveId, isDeepClone, preserveReadonlyTimestamps, preserveAutonumber))
Account ac = new account(Name = 'forum', billingcity = 'Texas', phone = '9999999999');
insert ac;    

//Deep cloning the above record
Account acCloneCopy  = ac.clone(true, true, false, false);
insert acCloneCopy;
It shows an error, because the Id is also considered and cannot insert the deppcloned record:
User-added image

Best Regards,
BALAJI
 
This was selected as the best answer
PlatFormCloudPlatFormCloud
Thanks Balaji!. Appreciate for the help.
ANAMIKA MONDAL 8ANAMIKA MONDAL 8
Hi all, Can anyone plese help me understand the parameters we are passing for the clone or deepclone methods. On which basis or for what we are passing true and false and how many of it?
Phil WPhil W
Apex supports clone against Object, not just SObject. I found the documentation for "clone" to be inadequate and I had to write some test code to see what the actual behaviour is, at least in the context of Map and List.

The "clone" method documentation should describe how just the "root object" is cloned (the object on which clone is called), whilst nested/referenced objects are maintained by reference (and not copied by value), whether these are SObjects or other Apex objects.

For example, cloning a Map<String, List<String>> will create a new map with new map entries but the same keys and values; each value (a list) is shared between the maps. Since lists are mutable this is problematic; updating a list from one map will update it in the other map (since it is shared).

Unfortunately, deepClone cannot be used with anything that isn't SObject based. The cloner code must do more. Continuing this example, the values can be cloned too via:

for (String key : myMap.keySet()) {
    myMap.put(key, myMap.get(key).clone());
}

Since String instances are immutable there is no harm sharing these between maps/lists/sets/objects.

Such an example really should appear in the documentation.
doughauck-corpdoughauck-corp
Did anyone else ever find any documentation on the Object (not SObject) cloning? 

I tried to implement a clone() method on one of my Apex classes, and it told me the method already exists.  Took me forever to figure out that's because it comes from the base Object class that all Apex classes inherit from.  I kept thinking I had somehow created it accidentally. 

The Object base class is the best-kept secret in Apex.  I've never found any official documentation about it, and the un-official documentation I've found says it only has 2 methods: hashcode() and equals(object).  Guess we can add a third now.  (Oh, and if you're thinking of using the 'override' keyword for your own clone() method, don't bother.  The one inherited from Object can't be overridden, and you will get the error: "@override specified for non-overriding method".)

I will have to use deepclone() for my method, though that's not an intuitive name for those not already familiar with the concept.  Wish I knew what purpose a clone() method serves on a root class like Object.  With no knowledge of the structure of any child class (which for a root class is ALL the classes) it could only make the absolute shallowest of copies.  So why have it at all?
Phil WPhil W
That's an interesting find. From the meta data perspective, my IDE says that Object includes just:
 
global class /*System.*/Object 
{
    global virtual Boolean equals(Object obj) {...}

    global virtual Integer hashCode() {...}

    global virtual String toString() {...}
    }
}
The fact that there is a clone method hidden in there implies, to me, one of two things:
  1. It is a "hidden" feature explicitly defined and used in the Apex infrastructure, "not for use outside Salesforce"
  2. The Apex Object class is actually accidentally exposing the underlying Java Object methods (https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html)
doughauck-corpdoughauck-corp
Well if it's #2, it doesn't expose any of the other Java Object methods, besides those you mentioned.  (I checked.)  So probably #1, though technically the whole Object class is "hidden", at least as far as telling us anything about it.

It obviously is just copying the block of memory directly - no other implementation would work so universally - and I can see why that's not code you'd want to cut/paste individually into all your child classes.  But there had to be a way to give themselves access to the Java super class method (to do the hard work) without making a public, non-virtual Apex method that basically locks the rest of us out of using that signature in Every. Other. Class.  (I'm thinking something like VS's internal scope keyword.  Or just, y'know, add the virtual keyword to it in the Apex Object.) 

Eh, whatev's - no sense crying over what can't be helped, as grandma always said.  Incidentally, what IDE are you using?  A good alternative to the somewhat clunky Developer Console would be much appreciated.
Phil WPhil W
I'm using Illuminated Cloud 2 within IntelliJ IDEA. An excellent combination for Salesforce development. We use them with git (Bitbucket and Bitbucket Pipelines for Continuous Integration) with SFDX development of a first generation managed package.