i am trying to solve this error but not able to solve, can anyone plz help me out. i have already set the standard pricebook.


System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId] Error is in expression '{!Save}' in component in page gen_multi_edit: Class.GEN_ProductSelectionController.save: line 89, column 1

Class.GEN_ProductSelectionController.save: line 89, column 1


public class GEN_ProductSelectionController {

    ID objCurrentOppId = ApexPages.currentPage().getParameters().get('id');    

     Public List<OpportunityLineItem> opportunityLineItemList{get;set;}
     public List<wrapOpportunityLineItem> wrapper{get;set;}
     public List<wrapProduct> wrapProductList {get; set;} //Used for Search button
     public List<PricebookEntry> selectedProducts{get;set;}
     public String searchstring {get;set;}      

    //First page wrapper class
    public class wrapProduct {
            public PricebookEntry priceBookEntryList{get; set;}
            public Boolean selected {get; set;}

            public wrapProduct(PricebookEntry p) {
                priceBookEntryList= p;
                selected = false;

    //Display the products already available
    public GEN_ProductSelectionController(){
             wrapProductList = new List<wrapProduct>();

             for(PricebookEntry a: [select Id, Name,ProductCode,UnitPrice,product2.Type__c from PricebookEntry]) {
             wrapProductList.add(new wrapProduct(a));
             System.debug('Default product list :' +wrapProductList);

     public void search(){  
             wrapProductList = new List<wrapProduct>();
             string searchquery='select name,id,Product2Id,ProductCode,UnitPrice,product2.Type__c from PricebookEntry where name like \'%'+searchstring+'%\' Limit 20';  

             for(PricebookEntry a: Database.query(searchquery)) {
                  wrapProductList.add(new wrapProduct(a)); //adding the searched products into list
                System.debug('Searched product list:' +wrapProductList);  

   //Select button funtion
     public PageReference selectProduct() {
        selectedProducts = new List<PricebookEntry>();

            for(wrapProduct wrapProductObj : wrapProductList) {

                 if(wrapProductObj.selected == true) {
                 System.debug('Selected product list : ' +selectedProducts);

            //system.debug('selectedWrapperList size ---------'+selectedProducts.size());
            PageReference pagePrice = new PageReference('/apex/GEN_Multi_Edit?id='+objCurrentOppId);
            opportunityLineItemList = [Select Quantity,UnitPrice,TotalPrice,Monthly_Revenue__c,Contract_Start_Date__c,Full_Revenue_Date__c,Service_Start_Date__c,OpportunityId,User_Define_Products__c from OpportunityLineItem ];
            System.debug('Opportunity Line Item List :' +opportunityLineItemList);

            wrapper = new List<wrapOpportunityLineItem>();
            for(Integer i=0; i<selectedProducts.size(); i++) {
            // Pass new OLI with opportunity id

            wrapper.add(new wrapOpportunityLineItem(new OpportunityLineItem(OpportunityId = objCurrentOppId, User_Define_Products__c = objCurrentOppId, PricebookEntryId = selectedProducts[i].Id),
                                       selectedProducts[i]) );

            return pageprice; 


    public PageReference Deletes() {
        return new PageReference('/'+objCurrentOppId);

      public PageReference save() {
          List<OpportunityLineItem> lstOLI = new List<OpportunityLineItem>();
          System.debug('Wrapper class:' +wrapper);
          for(wrapOpportunityLineItem obj :wrapper) {
          insert lstOLI;
          return new PageReference('/'+objCurrentOppId);

//Clear button code on GEN_Product_Selection     
      public PageReference Reset() {
            return new PageReference('/apex/GEN_Product_Selection?id='+objCurrentOppId);

    //Wrapper class for Gen_MultiEdit Page
    public class wrapOpportunityLineItem{

            public OpportunityLineItem oppLineItem{get;set;}
              public PricebookEntry selProd{get;set;}

            public wrapOpportunityLineItem(OpportunityLineItem oli, PricebookEntry sp)

               oppLineItem = oli;
               selProd = sp;


  • You opportuity.Pricebook2Id should be equal with OLI.Priceboo2Id
    – Ratan Paul
    Commented Feb 18, 2016 at 6:40
  • Alright but where do I check that in this controller?
    – Sharma_raj
    Commented Feb 18, 2016 at 6:47
  • 1
    I suggest display only those pricebookEntry records where pricebookEntry.PriceBook2Id == opportunity.PriceBook2Id
    – Ratan Paul
    Commented Feb 18, 2016 at 7:00
  • As through various links I found that I'll have to compare these but didn't understand where and why?
    – Sharma_raj
    Commented Feb 18, 2016 at 7:02
  • Okay I'll be trying that solution.
    – Sharma_raj
    Commented Feb 18, 2016 at 7:03

2 Answers 2


Like I said in comment your Opportunity.Pricebook2Id should be equal to your OLI.pricebookEntry.Pricebook2Id

So for solution what you can do..

Query only those PricebookEntry where pricebookEntry.Pricebook2Id = Opportunity.Pricebook2Id

change your query in constructor and search method..

Note: Please be insure your opportunity pricebook2Id not null

public with sharing class pageclass {

public GEN_ProductSelectionController(){

    wrapProductList = new List<wrapProduct>();
    Id objPricebook2Id = [SELECT Pricebook2Id FROM Opportunity 
                           WHERE Id =: objCurrentOppId]; 
    for(PricebookEntry a: [select Id, Name,ProductCode,UnitPrice,product2.Type__c 
                            from PricebookEntry WHERE PriceBook2Id =: objPricebook2Id]) {
      wrapProductList.add(new wrapProduct(a));
    System.debug('Default product list :' +wrapProductList);

Also in your search method change PricebookEntry query and add filter PriceBook2Id =: objPricebook2Id


For CPQ users - The test methods or test data factory you wrote (or perhaps inherited like I did) likely use Test.getStandardPricebookId(); to set the Pricebook2Id field of PriceBookEntry records. However, CPQ automation (such as, when a Contract is saved with "Renewal Forecast" checked) may set the pricebook2 field of a record (such as, the renewal Opp) to be a different Pricebook. Solution in my case was to set the non-matching records to the Test.getStandardPricebookId() pricebook as well. I tried changing the pricebook of the pricebookentry records but the field is not writeable.

You must log in to answer this question.

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