I am trying to add an OpportunityLineItem to an Opportunity and having some challenge with PricebookEntry.

Here is my Apex function:

public static void saveRecord(List recList3){

List<PricebookEntry> pbes = [SELECT Id, PriceBook2Id, Product2Id, Product2.Id, Product2.Name FROM PriceBookEntry WHERE Product2Id IN: recList3 AND PriceBook2.isActive=true LIMIT 1];

    for(Integer y = 0, aValue = recList3.size(); y < aValue; y++){
        OpportunityLineItem oli = recList3[y];
        oli.PriceBookEntryId = pbes.Id;
    insert recList3;

My Apex function receives a List of OpportunityLineItems Object like this:


What I need is to go through my OpportunityLineItems List, do a SOQL to find the PricebookEntryId that matches the Product2Id and add it to recList3.

I have 2 errors: -Invalid bind expression type of OpportunityLineItem does not match domain of foreign key -Variable does not exist: Id

Thanks for helping me

1 Answer 1


You are correct, before you can add OpportunityLineItems, you need to assign a value to Opportunity.Pricebook2Id. The Salesforce UX does this all for you behind the scenes when you add Opportunity products (because the dialog prompts you for the Pricebook)

But, if you are doing this in Apex, then you have to do the steps manually, 1x1

Opportunity o = new Opportunity(Name = 'xx',
                                Stagename = 'ss',
                                CloseDate = Date.today(),
                                Pricebook2Id = thePricebook2Id
 insert o;

 OpportunityLineItem oli = new OpportunityLineItem(
                                  OpportunityId = o.Id,
                                  Quantity = qty,
                                  PricebookEntryId = thePricebookEntryId
 insert oli;

where thePricebookEntryId is the ID of the junction record (PricebookEntry) that links the PriceBook2 corresponding to the Opportunity's Pricebook2Id and the Product2 (for the SKU of the OpportunityLineItem)

  • Hi @cropredy, I was editing my post at the same time so it changes a bit. The opportunity I am in already exist. I am adding oli from a component I created. If I look at your code, I will need to update the opp with thePricebook2Id that I am not sure where to get than add my lineItem. To get the PBE I need to SOQL that object and matches with the Product2Id no?
    – Eric
    Commented Apr 6, 2021 at 1:18
  • Yes, the PricebookEntry will need to be queried to get its Id : SELECT Id FROM PricebookEntry WHERE Pricebook2Id = theIdofthePricebook2 AND Product2Id = theIdOftheProduct2
    – cropredy
    Commented Apr 6, 2021 at 1:24
  • Got it! Not sure this is the right way to do so but it works. I don't like putting a SOQL inside a loop and setting a list all the time. Do you have a better way? for(Integer y = 0, aValue = recList3.size(); y < aValue; y++){ OpportunityLineItem oli = recList3[y]; List<PricebookEntry> pbe = [SELECT Id FROM PricebookEntry WHERE Pricebook2Id = '01s6g0000037ZybAAE' AND Product2Id =: recList3[y].Product2Id]; oli.PriceBookEntryId = pbe[0].Id; } insert recList3;
    – Eric
    Commented Apr 6, 2021 at 2:01
  • don't do soql in a for loop -- build a map of the necessary PBEs before you start constructing the OLIs
    – cropredy
    Commented Apr 6, 2021 at 2:03
  • another question (last) :) normally, when creating an opp, you add lineItems, create a quote and sync, the quote will take the products from the opp and create quotelineitems, If you add a quotelineitem, it will add it to the opps because is it sync. My solution deletes the opportunitylineitems when trying to sync :( any idea why?
    – Eric
    Commented Apr 6, 2021 at 2:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .