0

I am creating a clone opportunity line item in apex. However when I manipulte the fields of this clone, the original record is also being manipulated.

Does anyone have any idea why this is happenning?

    for(OpportunityLineItem oli : prodList)
    {  
        System.debug('#### CURRENT LINE ITEM: ' + oli);          

        Boolean createItem = true;

        Decimal usedQty;
        Decimal usedPrice = oli.UnitPrice;//Set Default Price

        if(oli.PricebookEntry.Product2.Family == 'Admin' || oli.PricebookEntry.Product2.Family == 'DOC' || oli.PricebookEntry.Product2.Family == 'Bin Insurance')
        { 
            OpportunityLineItem renewedOli = oli;

            oli.Invoiced__c = 'YES'; //Mark the OLI is invoiced so it will become inactive.
            oneOffPayments.add(oli);
            System.debug('#### CURRENT OLI: ' + oli);
            System.debug('#### RENEWED OLI: ' + renewedOli);

            if(oli.PricebookEntry.Product2.Name == 'DOC')
            {
                renewedOli.id = null;
                renewedOli.PricebookEntryId = '01uD000000OiyoKIAR';
                renewedOli.ServiceDate = oli.Opportunity_Close_Date__c.addYears((oli.ServiceDate.year() - oli.Opportunity_Close_Date__c.year()) + 1);
                renewedOli.Contact_Sent__c = null;
                renewedOli.Contract_Signed__c = null;
                renewedOli.Ordered__c = 'N/A';
                renewedOli.Order_Confirmed__c = 'N/A';
                renewedOli.Schdule_Of_Service_Sent__c = 'N/A';
                renewedOli.Delivered__c = 'N/A';
                renewedOli.Had_First_Collection__c = 'N/A';
            }

            if(oli.PricebookEntry.Product2.Name == 'Bin Insurance')
            {
                renewedOli.id = null;
                renewedOli.PricebookEntryId = '01uD000000UXG1iIAH';
                renewedOli.ServiceDate = oli.Opportunity_Close_Date__c.addYears((oli.ServiceDate.year() - oli.Opportunity_Close_Date__c.year()) + 1);
                renewedOli.Contact_Sent__c = null;
                renewedOli.Contract_Signed__c = null;
                renewedOli.Ordered__c = 'N/A';
                renewedOli.Order_Confirmed__c = 'N/A';
                renewedOli.Schdule_Of_Service_Sent__c = 'N/A';
                renewedOli.Delivered__c = 'N/A';
                renewedOli.Had_First_Collection__c = 'N/A';
            }
            renewals.add(renewedOli); //Add the renewal OLI to list ready to be inserted.

            System.debug('##### ORIGINAL OLI: ' + oli);
            System.debug('##### RENEWED OLI: ' +renewedOli);

In the debug the original oli and renewed oli are both having identical values copied to each other. Why??? Only renewed should be getting affected with this code.

  • 2
    cant see you using clone method, You are just modifying the same record – Pranay Jaiswal Jan 24 at 12:24
3

You aren't cloning the sObject, you're just assigning another reference to it.

OpportunityLineItem renewedOli = oli;

This creates a second name, renewedOli, that refers to the same in-memory sObject instance as oli. It does not create a copy.

In Apex, as in most object-oriented languages, objects other than primitives are passed and assigned by reference. This means that when you assign an sObject value, or pass it as a parameter to a function, that function receives a reference to the original sObject, which it can mutate on an equal footing with the original reference to that sObject. Note that this is distinct from primitive values like Integers, which are passed by value: if I do

Integer i = 2;
Integer j = i;

j = 3;
System.assertEquals(2, i, 'unchanged');

my assertion will pass, because the primitive value was copied by value, and not passed by reference.

To create a copy of your OpportunityLineItem, you'll need to call oli.clone(false, false, false, false);

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.