+ Start a Discussion
Zach AlexanderZach Alexander 

Dataloader: trigger works batch size 1 -- explodes otherwise. (Amateur Developer)

Hello Everyone,

Primary Question: Can someone pinpoint what we are doing wrong in our Trigger below?

Background: The purpose of this trigger is to "break up" large single payments (Fleet Lease Pay) made by business clients and create parallel records showing the payments per vehicle (Fleet Truck Pay). Each "Fleet Truck Pay" record needs to be linked to to both the original "Fleet Lease Pay" and another custom object called "Vehicle Inventory". This is important because we track payments made per vehicle on the object called "Vehicle Inventory".

Problem: Our trigger works for manual entries of new "Fleet Lease Pay" records. However, when using the dataoloader (with batch size greater than 1) the trigger explodes and creates thousands upon thousands of records matching "Fleet Trucks" that aren't part of the parent "Fleet Lease". We have not been able to figure out a rhyme or reason to this explosion. We figure the data is getting blended together like the ingredients in a body-builder's smoothie. But we're not sure how.

Does anybody know why the information is getting blended up?

Fleet Lease Pay   =   Fleet_Lease_Payment__c
Fleet Lease   =   Fleet_Lease_ID__c or Fleet_Lease__c
Fleet Truck   =   Fleet_Truck__c
Fleet Truck Pay   =   Fleet_Vehicle_Payment__c
Vehicle Inventory   =   VIN_Vehicle_Inventory__c or Vehicle_Inventory__c

Relationship Diagram

Trigger Code:

trigger FleetLeasePaymentDivider on Fleet_Lease_Payment__c (after insert) {
    Set<Id> ids = Trigger.newMap.keySet();
    
    //Create all the lists needed for this process.
    List<Fleet_Truck__c> fleetVehicles = new List<Fleet_Truck__c>();
    List<String> leaseId = new List<String>();
    List<FLeet_Lease_Payment__c> fleetLeasePayments = new List<Fleet_Lease_Payment__c>();
    List<Fleet_Vehicle_Payment__c> fleetVehiclePayments = new List<Fleet_Vehicle_Payment__c>();
    List<Fleet_Truck__c> vehicles = new List<Fleet_Truck__c>();
    
    //Get Data from the "Fleet Lease Pay" Object.
    //Obtain the "Fleet Lease" Parent ID
    for (Fleet_Lease_Payment__c pmt : [SELECT Id, Fleet_Lease_ID__c, Lease_Amount__c, Date_Paid__c FROM Fleet_Lease_Payment__c WHERE Id IN :Trigger.new])
    {
        //Populate List of Fleet Lease Payments in Upload
        fleetLeasePayments.add(pmt);

        //Populate List of Parent IDs
        leaseId.add(pmt.Fleet_Lease_ID__c);
    }
    
    //Get List of all the Fleet Trucks attached to Parent
    for (Fleet_Truck__c fleetUnit : [SELECT Id, Fleet_Lease__c, VIN_Lookup__c FROM Fleet_Truck__c WHERE Fleet_Lease__c IN :leaseId])
    {
         //Populate List of Fleet Trucks attached to parent
         fleetVehicles.add(fleetUnit);
    }
    
    //Start final phase of trigger by cycling through each Fleet Lease Payment
    for (FLeet_Lease_Payment__c FLPmt : fleetLeasePayments)
    {
        //Make Parent ID easy to reference
        String fleetLeaseId = FLPmt.Fleet_Lease_ID__c;
        
        //Summon back up the list of all Fleeet Trucks attached to Parent
        for (Fleet_Truck__c fleetTruck : fleetVehicles)
        {
            //Check to see if the the Fleet Lease Pay and Fleet Truck records belong to the same parent
            if (fleetTruck.FLeet_Lease__c == fleetLeaseId)
            {
                //If so, Populate a second list of trucks, that is specific to each Fleet Lease Pay record
                vehicles.add(fleetTruck);
            }
        }
        //Get the second list of trucks we just made
        for (Fleet_Truck__c truck : vehicles)
        {
            //Create Fleet Truck Payment Records from that data
            Decimal truckPmt = FLPmt.Lease_Amount__c / vehicles.size();
            Fleet_Vehicle_Payment__c fleetPmt = new Fleet_Vehicle_Payment__c(Date_Paid__c = FLPmt.Date_Paid__c,
                                                                             Fleet_Lease_Payment__c = FLPmt.Id,
                                                                             VIN_Vehicle_Inventory__c = truck.VIN_Lookup__c,
                                                                             Fleet_Vehicle__c = truck.Id,
                                                                             Lease_Amount__c = truckPmt);
            //Populate the Fleet Truck Payments we want to Upload
            fleetVehiclePayments.add(fleetPmt);
        }
    }
    
    //Check to see if there is anything in the list.
    if (!fleetVehiclePayments.isEmpty())
    {
        //If so, insert the list.
        insert fleetVehiclePayments;
    }
}
Best Answer chosen by Zach Alexander
Vj@88Vj@88
You just need to clear the values in the list vehicles after every loop. Write the statement Vehicles.clear() at end of for loop.
for (FLeet_Lease_Payment__c FLPmt : fleetLeasePayments)
    {
        //Make Parent ID easy to reference
        String fleetLeaseId = FLPmt.Fleet_Lease_ID__c;
        
        //Summon back up the list of all Fleeet Trucks attached to Parent
        for (Fleet_Truck__c fleetTruck : fleetVehicles)
        {
            //Check to see if the the Fleet Lease Pay and Fleet Truck records belong to the same parent
            if (fleetTruck.FLeet_Lease__c == fleetLeaseId)
            {
                //If so, Populate a second list of trucks, that is specific to each Fleet Lease Pay record
                vehicles.add(fleetTruck);
            }
        }
        //Get the second list of trucks we just made
        for (Fleet_Truck__c truck : vehicles)
        {
            //Create Fleet Truck Payment Records from that data
            Decimal truckPmt = FLPmt.Lease_Amount__c / vehicles.size();
            Fleet_Vehicle_Payment__c fleetPmt = new Fleet_Vehicle_Payment__c(Date_Paid__c = FLPmt.Date_Paid__c,
                                                                             Fleet_Lease_Payment__c = FLPmt.Id,
                                                                             VIN_Vehicle_Inventory__c = truck.VIN_Lookup__c,
                                                                             Fleet_Vehicle__c = truck.Id,
                                                                             Lease_Amount__c = truckPmt);
            //Populate the Fleet Truck Payments we want to Upload
            fleetVehiclePayments.add(fleetPmt);
        }
      Vehicles.clear();
    }

All Answers

Vj@88Vj@88
You just need to clear the values in the list vehicles after every loop. Write the statement Vehicles.clear() at end of for loop.
for (FLeet_Lease_Payment__c FLPmt : fleetLeasePayments)
    {
        //Make Parent ID easy to reference
        String fleetLeaseId = FLPmt.Fleet_Lease_ID__c;
        
        //Summon back up the list of all Fleeet Trucks attached to Parent
        for (Fleet_Truck__c fleetTruck : fleetVehicles)
        {
            //Check to see if the the Fleet Lease Pay and Fleet Truck records belong to the same parent
            if (fleetTruck.FLeet_Lease__c == fleetLeaseId)
            {
                //If so, Populate a second list of trucks, that is specific to each Fleet Lease Pay record
                vehicles.add(fleetTruck);
            }
        }
        //Get the second list of trucks we just made
        for (Fleet_Truck__c truck : vehicles)
        {
            //Create Fleet Truck Payment Records from that data
            Decimal truckPmt = FLPmt.Lease_Amount__c / vehicles.size();
            Fleet_Vehicle_Payment__c fleetPmt = new Fleet_Vehicle_Payment__c(Date_Paid__c = FLPmt.Date_Paid__c,
                                                                             Fleet_Lease_Payment__c = FLPmt.Id,
                                                                             VIN_Vehicle_Inventory__c = truck.VIN_Lookup__c,
                                                                             Fleet_Vehicle__c = truck.Id,
                                                                             Lease_Amount__c = truckPmt);
            //Populate the Fleet Truck Payments we want to Upload
            fleetVehiclePayments.add(fleetPmt);
        }
      Vehicles.clear();
    }
This was selected as the best answer
Zach AlexanderZach Alexander
Sir... I think you are my hero :)

Will test this out as soon as we can. Looking at your answer, now it makes sense why the program was blowing up on us.
Zach AlexanderZach Alexander
It works like a charm now :)