1

I am cloning a custom sobject inside a 'before update' trigger and updating the values for some of the fields on the cloned sObject. However when I run the code, it throws a NullPointerException.

List<CustomObject__c> coList = getOriginalCustomObjects();
if(coList != null) {
  for(CustomObject__c co : coList) {
    CustomObject__c clonedCO = (CustomObject__c) co.clone(false, true, false, false);
    if(clonedCO != null) {
      clonedCo.version__c = 2.0; //This is where I get NullPOinterException
      System.debug('is clonedCo null? '+(clonedCo == null)); //outputs false
   }
  }
}

I am not sure why it thinks the cloned sObject is Null and throws

NullPointerException at line 6 (clonedCo.version__c);

I then insert the list of cloned custom objects.

  • 1
    If you were doing e.g. clonedCo.version__c += 1.0; then the field being null would cause an NPE; don't see how the code as posted would NPE. – Keith C Jan 26 '16 at 11:09
  • What is your trigger event? i think you are using before insert here... – Peeyush Jan 26 '16 at 11:16
  • @KeithC so it turns out that when you clone an object, it only clones fields with values from the original object. Otherwise, it treats that field as Null. In this case the version__c field was empty and therefore was not "cloned", and hence the NullPointerException. – Anup Jan 26 '16 at 11:25
  • @Anup this shouldn't be the case. Even if clonedCo.version__c is null, it shouldn't throw NPE. I tried the below code and works fine for me: TestObject__c to2 = new TestObject__c(); to2.name = 'abc'; TestObject__c cloneTo2 = to2.clone(false, true, false, false); cloneTo2.Amount__c = 70; – Lance Shi Jan 26 '16 at 11:30
  • @LanceShi, this is running in a trigger context. And the way I fixed the problem was by checking that clonedCo.version__c is not null, and the problem went away. – Anup Jan 26 '16 at 11:32
0

After much debugging and guessing, I found out that when you clone an sObject inside a before update trigger context, it only clones fields that are not "empty". So if the field on the original sObject record is null or empty, it won't end up in the list of fields available to your cloned sObject in memory, and it will throw a NullPointerException. Something that is not pointed out explicitly in the documentation.

In this instance, the version__c field in the original object was empty, and therefore was not copied in the clonedCO sObject. This was the reason the code was throwing a NullPointerException.

Hope this solution helps someone else in the future!

| improve this answer | |
  • So I am trying to replicate your issue like above you said.. But not able to replicate issue.. tried this Opportunity objOpp1 = [SELECT Id, TotalOpportunityQuantity FROM Opportunity WHERE TotalOpportunityQuantity = null limit 1]; Opportunity objOpp2 = objOpp1.clone(false, true, false, false); objOpp1.TotalOpportunityQuantity = 22; Also tried Account objAccount = new Account(); Account objAcc1 = objAccount.clone(false, true, false, false); objAcc1.Name = 'Test'; Just curious what i am missing – Ratan Paul Jan 26 '16 at 12:02
  • @Ratan that won't work because Name in the original objAcc1 is not empty or null. Choose a field that is empty or null in the original objAcc1 record, and try it again. – Anup Jan 26 '16 at 12:15
  • Anup what about above opportunity example ? – Ratan Paul Jan 26 '16 at 12:17
  • @Ratan, is the TotalOpportunityQuantity empty or null in the objOpp1 record? If not, then it will be cloned in memory and won't throw an exception. – Anup Jan 26 '16 at 12:18
  • Anup you can see the query. I queried a opportunity record where TotalOpportunityQuantity is null and then cloned and trying set value objOpp1.TotalOpportunityQuantity = 22; but it is working.. not giving NPE. – Ratan Paul Jan 26 '16 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.