0

I had a requirement where i need to create records based on the Campaign Members in the Opportunitie.i had done the trigger and the code was working fine but today i had an error

Error:Apex trigger CreateList caused an unexpected exception, contact your administrator: CreateList: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0 with id 0062800000CMrpPAAT; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]: Trigger.CreateList: line 34, column 1

Trigger CreateList on Campaign ( after insert ) {
List<Opportunity> opp = new List<Opportunity>(  );
List <OpportunityContactRole> ocrole = new List<OpportunityContactRole>(  );
public integer iOPPCount {get; set;
}

public integer icount {get; set;
}

for( Campaign camp : trigger.new ){
    if( camp.Create_List__c == True ){
        String sCamp= String.valueof( camp.id );
        iOPPCount  = [SELECT count(  ) FROM CampaignMember WHERE CampaignId =:sCamp];
        if ( iOPPCount  > 0 ){                
            // camp.addError( String.Valueof( iOPPCount ) );
            List<CampaignMember> camps = [SELECT id,FirstName,LastName,CompanyOrAccount,ContactId FROM CampaignMember WHERE CampaignId =:sCamp];            

            for( CampaignMember CM : camps ){
                String sEvent = String.valueof( camp.EventIDName__c );
                String sName = String.valueof( CM.FirstName ) + ' ' + String.valueof( CM.LastName );
                icount = [SELECT count(  ) FROM Opportunity WHERE Campaign__c =:camp.Id and Name=:sEvent +'-' + sName];

                if ( icount == 0 ){                    

                    // camp.addError( sEvent + '-' + sLast );
                    //Opportunity  op = new Opportunity( Campaign__c=camp.Id,Name=sEvent+ '-' + sName,CloseDate=camp.EndDate,StageName='Prospecting' ); 
                    Opportunity op = new Opportunity( 
                    Campaign__c=camp.Id,
                    Name=sEvent +'-' + sName,
                    CloseDate=camp.EndDate,
                    StageName='Prospecting',
                    Contact__c= cm.ContactId );                                                            
                    opp.add( op );                                                                       

                }

                insert opp;    

                for( Opportunity ops : opp ){
                    string sOppId = String.Valueof( ops.get( 'id' ) );
                    string sConId = String.Valueof( ops.get( 'Contact__c' ) );
                    // camp.addError( String.Valueof( opp[0].id ) );        

                    OpportunityContactRole ocr = new OpportunityContactRole( 
                    OpportunityId = sOppId,
                    //ContactId = cm.ContactId,
                    ContactId = sConId,
                    IsPrimary = TRUE );
                    ocrole.add( ocr );

                }

                insert ocrole;    

                // insert ocrole;        

            }


        }
         else if( iOPPCount  < 0 ){
            //do nothing

        }

        /*  {
            List<Contact> OPPList =[Select Name from  Contact];
            for ( Contact OPP : OPPList  )
            {
                String sOPPList= String.Valueof( OPP.get( 'Name' ) );
                Opportunity o = new Opportunity( Campaign = camp.id, Name=camp.Name + '-' + sOPPList ,Contact__c =camp.Contact__c );
                ot.add( o );

            }

            insert ot;

        }
         */

    }


}

}

2
  • 1
    I think that the error message(cannot specify Id in an insert call) is pretty clear. I would also suggest you spending a few minutes to indent your code better. And I immediately see a lot of queries and DML operations inside loops, which is certainly not a best practice.
    – Novarg
    Commented Aug 31, 2016 at 10:06
  • Your opp list includes objects that have already been inserted - and so have Id values assigned - if the loop is gone round more than once. The way to fix is (as Novarg points out) to move the DML and queries out of the loop.
    – Keith C
    Commented Aug 31, 2016 at 10:15

1 Answer 1

0

What is happening here is that you are re-inserting the List of Opps every time the loop runs. So on first loop you are inserting with 1 Opp, on the second run you are inserting with 2 Opps (the first one that was already inserted and the new one).

You cannot insert a record that already exists (has an Id), thus the error you are seeing.

There are two things you can do here.

  1. The right way.

Move your DML outside of the loop - this is standard best practice and you should be doing it anyway.

  1. The quick and wrong way.

Change your insert to an upsert. I highly recommend against this but it should fix your issue.

You must log in to answer this question.

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