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
GoForceGoGoForceGo 

Trigger - before and after update size is different....

I am working on a test method and it is crashing.

 

I have an after update trigger on lead  where I am testing if lead is converted, and if so  I am updating a list of custom objects Y (through update statement).

I have verified that there are two distinct entries in the array through debug logs.

 

In the before update trigger of the custom object Y ,  I see that the trigger.new.size() is 2.

In the after update trigger of the custom object Y, the trigger.new.size() is 1. The trigger.old.size() is 1 as well.

One of the two objects in the original list is missing in the after update trigger.

 

How could this be?

 

FYI, When I try to simulate what I am doing in the test method through UI, it does not crash.

 

 

 

 

 

Rocky.4QRocky.4Q

is the update being called in a for loop? or is an List being updated?

GoForceGoGoForceGo

The list is being updated.

Shashikant SharmaShashikant Sharma

You must be updating the same object record on which you have trigger. And the size of the list of records same object is one and that is taking you back in trigger for those record.

 

its like

 

List<Account> l =  new List<Account>();

l.add(new account('a');

l.add(new account('b');

insert l;

 

now if in trigger

 

trigger updateAccount on Account(after insert, before update   , after update )

{

    Account a = trigger.new.get(0);

    if(a.name == 'a'){

    a.name = 'updatename';

    update a;

   }

}

GoForceGoGoForceGo

The before update and after update size difference the symptom rather than the problem.

 

The problem seems to be something to do with lead conversion.

 

Here is what I am trying to test.

 

I have a "shadow lead" object for every lead i.e a shadow lead points to a lead.  When two leads are merged, both shadow leads will point back to the merged  lead.When this merged lead is converted to a contact, I want the two shadow leads to point to the new contact. I am setting the value of this contact on shadow leads and trying to update the two shadow leads.  The system does not want to update the SECOND shadow lead.

 



As I said, when I do this in UI, everything works fine - I can see the two shadow leads on the contact.  Seems like when called from Database.ConvertLead, I run into this issue.


 

Here is onconvert method.

 

trigger onconvert on Lead (after update) {

Map<Id,Lead> convertedLeadsMap = new Map <Id,Lead> ();

Lead[] OldLeads = Trigger.old;
Lead[] newLeads = Trigger.new;

for (integer i=0; i < newLeads.size(); i++) {
Lead newLead = newLeads[i];
Lead oldLead = oldLeads[i];
if (newLead.isConverted && !oldLead.isConverted) {
convertedLeadsMap.put(newLead.id, newLead);
}
}

if (convertedLeadsMap.size() == 0) return;

Shadow_Lead__c[] ShadowLeads = [select Lead__c, Contact__c from Shadow_Lead__c where Lead__c in :convertedLeadsMap.KeySet()];

for (Shadow_Lead__c sLead:ShadowLeads) {
Lead l = convertedLeadsMap.get(sLead.Lead__c);
if (l.ConvertedContactId != null) {
sLead.Contact__c = l.ConvertedContactId;
}
}
update ShadowLeads; //THIS CRASHES

}

 

My test method.

 

   static testMethod void testShadow () {

Lead l2 = new Lead(FirstName = 'Test', LastName = 'Lead', Company = 'Test Company', Email = 'x2@hotmail.com');
insert l2;
Shadow_Lead__c sl2 = [select id from Shadow_Lead__c where Lead__c = :l2.id];
Lead l3 = new Lead(FirstName = 'Test', LastName = 'Lead', Company = 'Test Company', Email = 'x3@hotmail.com');
insert l3;
Shadow_Lead__c sl3 = [select id from Shadow_Lead__c where Lead__c = :l3.id];
merge l2 l3;
//l3 was merged and hence deleted
integer count = [select count() from Lead where id = :l3.id];
System.ASSERT(count == 0);
sl2 = [select Lead__c from Shadow_Lead__c where id = :sl2.id];
sl3 = [select Lead__c from Shadow_Lead__c where id = :sl3.id];

System.ASSERT(sl3.Lead__c == l2.id);
System.ASSERT(sl2.Lead__c == l2.id);

Database.LeadConvert lc = new database.LeadConvert();
lc.setLeadId(l2.id);
LeadStatus convertStatus = [Select Id, MasterLabel from LeadStatus where IsConverted=true limit 1];
lc.setConvertedStatus(convertStatus.MasterLabel);

Database.LeadConvertResult lcr = Database.convertLead(lc);
}

 When the Database.convertLead method is called, I get the following exception - this is a crash at  "update ShadowLeads" statement in the trigger.

 

  System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00QE00000021QQUMA2; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, onconvert: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 1 with id a0GE0000000Zw2BMAS; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: [] Trigger.onconvert: line 26, column 5: [] (System Code) External entry point: []

 

The before/after update symption shows up if I have before/after update trigger on ShadowLead, the before trigger has both shadow leads, the after update has only the first one. Of course, without the Shadow Lead triggers, it still crashes. 

GoForceGoGoForceGo

If I null out the Lead on shadow lead, it works.

 

I could be wrong, but this appears to be a bug in SFDC.


From UI everything works, but calling Database.LeadConvert does not work, unless you get rid of reference to the lead object.

 

    for (Shadow_Lead__c sLead:ShadowLeads) {
        Lead l = convertedLeadsMap.get(sLead.Lead__c);
        if (l.ConvertedContactId != null) {
            sLead.Contact__c = l.ConvertedContactId;
            sLead.Lead__c = null; //this works. 
        }
    }