10
public class controllerName {
    public class WrapperClass {
        public CustomSObj__c custom {get; set;}
        public Boolean bool {get; set;}
        public WrapperClass(CustomSObjc__c custom) {
            this.custom = custom;
            bool = false;
        }
    }
    WrapperClass obj {get; set;} 

    WrapperClass clonedObj {get; set;}

    public ControllerName() {
        obj = new WrapperClass(...);
        clonedObj = obj.clone();
    }
}

I would like to know if the preceeding code performs a deep clone on the wrapped sObject, because I need an identical version of this wrapper and not just a copy of a pointer. From testing my application, it appears to do so, which is what I would like to happen. For example, calling System.assertEquals(obj.custom.id, clonedObj.custom.id) passes.

Am I correct?

2 Answers 2

9

For an Apex class like controllerName.WrapperClass you will only get a shallow copy clone.

I suspect you will need to create a new instance of WrapperClass using an sObject clone of the custom property.

Alternatively, you could serialize the data to JSON and then deserialize to create a clone. See the answer by Andrew Fawcett in Deep Clone (Parent -> Child -> Grand Child).


Also, have a look at the documentation for sObject.clone().

There are 4 optional boolean parameters that will affect the type of cloning you get:

  1. opt_preserve_id - is the ID of the original object preserved? Default is false.
  2. opt_IsDeepClone - Are any references cloned as well? Default is false.
  3. opt_preserve_readonly_timestamps - Are read-only timestamp fields preserved? Default if false.
  4. opt_preserve_autonumber - Are any auto number field values perserved. Default is false.

So a straight clone won't keep a number of fields, such as the primary record Id, timestamp, and auto number fields. These will all differ from the original record.

Also, any referenced fields won't be cloned by default, so "if you make changes to a relationship field on the cloned sObject, the corresponding field on the original sObject is also affected, and vice-versa".

You should set opt_IsDeepClone to true if you want a deep clone of the references within an sObject.

3
  • 1
    But is WrapperClass a subclass of SObject? This would contradict my understanding of the SObject class. May 5, 2013 at 22:22
  • @DanielBlackhall You are correct. Apex classes are not subclasses of sObject, but of Object (the java Object) and doing the following: obj.cone(false,true) throws the following error Method does not exist or incorrect signature: [WrapperClass].clone(Boolean, Boolean) May 5, 2013 at 22:53
  • 1
    @DanielBlackhall, good point. I'm no expert on the Java clone method. From what I've skim read it sounds like you get a shallow copy and you have to do deep copy yourself. May 5, 2013 at 23:19
7

No, it does not perform a deep clone. For wrapper classes you need to write your own clone method/constructor which does the cloning you need.

You must log in to answer this question.

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