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
Rolando EstevesRolando Esteves 

Inserting a List<custom object> trigger only fires once

Hi,

 

When I insert a list of a custom object in apex it only fires my before insert for the first object on the list.

 

Anyone knows why ??

 

Thanks

JonathanBaltzJonathanBaltz

Can you please provide code?  The issue will be easier to solve with the code that is causing the issue.

Thanks!

Rolando EstevesRolando Esteves

Here is the code: When I insert the AllUnit list it fires the trigger for the first item on the list only

 

public with sharing class UploadRecordUsingCSV {

    public UploadRecordUsingCSV(ApexPages.StandardController controller) {

    }

    
    public Blob FileRecords{get;set;}
    
    String[] LineNo= new String[]{};
    List<product_opportunity__c> AllUnit;
    
    Public Pagereference UploadFile()
     {
       system.debug('Enter');
       String FileData=FileRecords.toString();
       LineNo=FileData.split('\n');
       AllUnit = new List<product_opportunity__c>();
                system.debug('Entered****'+ AllUnit);
       for(Integer i=1;i<LineNo.size();i++)
        {
          product_opportunity__c pto = new product_opportunity__c();
          String[] ActualData=new String[]{};
          ActualData=LineNo[i].split(',');
          pto.Name = 'TEST';
          
          pto.OpportunityID__c = ActualData[0];
          pto.Part_Number__c = ActualData[1];
          pto.Vendor_Unit_Cost__c = double.valueOf(ActualData[2]);
          
          //AllUnit.add(pto);
          insert pto;
        }
       //insert AllUnit;
       return Null;
     }
}

 

JonathanBaltzJonathanBaltz

With this code at the end, the trigger will probably fire for every insert, but you will also hit your govornor limits as well. 

          //AllUnit.add(pto);
          insert pto;
        }
       //insert AllUnit;
       return Null;
     }
}

 If you comment out the "insert pto;" and uncomment the other two lines, you won't hit the governor limts. 

The code that you would have to update is the trigger code.  If you take a look at the first best practice in the Apex Code Best Practice wiki page, you will see that the need will be to do a for loop on each record in the trigger group. 

 

 

trigger accountTestTrggr on Account (before insert, before update) {

   List<String> accountNames = new List<String>{};
 
   //Loop through all records in the Trigger.new collection
   for(Account a: Trigger.new){
      //Concatenate the Name and billingState into the Description field
      a.Description = a.Name + ':' + a.BillingState
   }
   
}

 I hope that helps!

Rolando EstevesRolando Esteves

I know this is bad practice but can you help me bulkify this trigger:

 

trigger productsUploader on product_opportunity__c (before insert) {
    
     product_opportunity__c l_PTO = Trigger.new[0];
     l_PTO.PricebookEntryID__c = [select id from PriceBookEntry A 
                       where A.ProductCode = :l_PTO.Part_Number__c].Id;
}

 

JonathanBaltzJonathanBaltz
trigger productsUploader on product_opportunity__c (before insert) {
    
     for(product_opportunity__c l_PTO = Trigger.new){
        PriceBookEntry pbe = [select id from PriceBookEntry A 
                       where A.ProductCode = :l_PTO.Part_Number__c LIMIT 1];
     l_PTO.PricebookEntryID__c = pbe.Id;
}

 That should work.  If it does, please mark this entry as solved. 

Thanks!

Rolando EstevesRolando Esteves

You have  a SOQL query inside a forr loop i think it might have some problems with governor limits.

JonathanBaltzJonathanBaltz

That's a good point.  In that case...I just thought of this:  you're inserting these records, and the trigger is "before insert."

If you're already looking for the ID from the PriceBookEntry where the ProductCode matches l_PTO.Part_number__c...

If that's a lookup to the Product2 object, then you can get to the PriceBook that way....

 

Have you considered a workflow field update?  I'm not 100% that would work, but a formula to populate the field with the Part_Number__c (if its a lookup to Product) to the Pricebook to the PriceBookEntry...

 

Not 100% sure that will work, but the options are really vast.  If the Part_Number__c is a lookup to Product2, the best bet is to find the value through that chain of object relationships. 

Rolando EstevesRolando Esteves

There no possible way to achieve this trough out workflows or formulas. Thanks for the help so far!

I need to bulk my trigger without affecting governor limits.

 

it should go something like this:

 

trigger productsUploader on product_opportunity__c (before insert) {
    
     List<String> l_pto = new List<String> ();
     for(product_opportunity__c pto: Trigger.new)
     {
        //create the list of all the product codes
     }
     for(product_opportunity__c pto: [select id from PriceBookEntry A where A.ProductCode IN (// the list I think)])
     {
         // assign the correct PRiceBookID
     }
     product_opportunity__c l_PTO = Trigger.new[0];
     l_PTO.PricebookEntryID__c = [select id from PriceBookEntry A 
                                        where A.ProductCode = :l_PTO.Part_Number__c].Id;
                                        
     
}

 

JonathanBaltzJonathanBaltz

Is Part_Number__c a lookup to Product2?  If so, you can do it through the relationship between Product and Pricebook.  I'm not sure what you're trying to do is possible because it's going to create the list of all the Product Codes for every item in the Trigger. 

 

Maybe what you need is a lookup to Product on product_opportunity__c.  Or to Opportunity.  Both have a lookup to the Pricebook object. 

Rolando EstevesRolando Esteves

Product2 does not have a relation to the pricebookentry2. And from Opportunity you would need the OpportunityLineItem already created.

JonathanBaltzJonathanBaltz

The Product will have a relation to a Pricebook, even if it's the Standard Pricebook.  The Pricebook contains the Product price, and that pair is the PriceBookEntry.  If there is a Product, and there is a PriceBookEntry, there needs to be a Pricebook.  If you're trying to get the Pricebook entry for a Product, you're going to need the Pricebook.  It's a transitive relationship: if you have two, you can get the third. 

 

 

Rolando EstevesRolando Esteves

¿Can we call a another class passing the File as a parameter in order to process 75 more lines ?