1

ERROR 1 :

Subject: Developer script exception from Nicomatic : quotepotential : quotepotential: execution of AfterUpdate caused by: System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again. Trigger.quotepotential: line 14, column 1

Apex script unhandled trigger exception by user/organization: 00590000001A6jh/00D90000000bovq

quotepotential: execution of AfterUpdate

caused by: System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again.

Trigger.quotepotential: line 14, column 1

ERROR 2: same

Subject: Developer script exception from Nicomatic : batchtoquotelineitem : batchtoquotelineitem: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0L90000004mgNmEAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, quotepotential: execution of AfterUpdate caused by: System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again. Trigger.quotepotential: line 14, column 1: [] Trigger.batchtoquotelineitem: line 13, column 1

Apex script unhandled trigger exception by user/organization: 00590000001A6jh/00D90000000bovq

batchtoquotelineitem: execution of AfterUpdate

caused by: System.DmlException: Update failed. First exception on row 0 with id a0L90000004mgNmEAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, quotepotential: execution of AfterUpdate

caused by: System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again.

Trigger.quotepotential: line 14, column 1: []

Trigger.batchtoquotelineitem: line 13, column 1

can you correct this program to get rid of these two exceptions :

trigger quotepotential on Quote_Line_Item__c (after insert,after update) {
    Set<Id> quoteIds = new Set<Id>();
    List<Quote__c> quotes = new List<Quote__c>();
    for(Quote_Line_Item__c record: Trigger.new) {
    if (record.Quote1__c != null){
        quoteIds.add(record.Quote1__c);
    }
    }
    for(AggregateResult ar:[SELECT Quote1__c , SUM(Max_Batch__c)sumMax FROM Quote_Line_Item__c WHERE Quote1__c IN :quoteIds GROUP BY Quote1__c]) {
      Quote__C qu=new quote__c();
      qu.id=(Id)ar.get('Quote1__c');
      qu.Potential__c=(Decimal)ar.get('sumMax');
       quotes.add(qu);
       list<quote__c> quo = [select id,potential__c from quote__c where id IN :quotes limit 1 for update]; 
       update quo;
}
if(quotes.isempty() == false)
    {
  update quotes;
  }
}
1
  • 2
    what did you try?
    – superfell
    Nov 27, 2013 at 22:42

3 Answers 3

1

Since your trigger code isn't commented, it is unclear exactly what your intent is but I'll take a shot at correcting and commenting it.

trigger quotepotential on Quote_Line_Item__c (after insert, after update) {

    // the IDs of quotes which we are going to populate the potential amount on
    Set<Id> quoteIds = new Set<Id>();

    // the list of Quote__c records which will be updated with the amount
    List<Quote__c> quotesToUpdate = new List<Quote__c>();

    // collect the ID value of the related Quote
    for (Quote_Line_Item__c record: Trigger.new) {
        if (record.Quote1__c != null) {
            quoteIds.add(record.Quote1__c);
        }
    }

    // use the quoteIDs set to get the aggregate sum per Quote1__c
    for (AggregateResult ar : [SELECT Quote1__c
                                    , SUM(Max_Batch__c)sumMax 
                                FROM Quote_Line_Item__c
                                WHERE Quote1__c IN :quoteIds 
                                GROUP BY Quote1__c]) {

        // create an sObject to be used for the update operation
        Quote__c qu = new Quote__c(Id = (Id)ar.get('Quote1__c'));
        qu.Potential__c = (Decimal)ar.get('sumMax');

        // add this sObject to the updates list
        quotesToUpdate.add(qu);

        /* Not sure why this code is here - it appears to not belong */
        /* P.S. avoid DML operations in loops in all cases */
        // list<quote__c> quo = [select id,potential__c from quote__c where id IN :quotes limit 1 for update]; 
        // update quo;
    }

    // if there's work to be done, do it.
    if (!quotesToUpdate.isEmpty()) {
        update quotesToUpdate;
    }
}
3
  • 1
    /* Not sure why this code is here - it appears to not belong / / P.S. avoid DML operations in loops in all cases */ // list<quote__c> quo = [select id,potential__c from quote__c where id IN :quotes limit 1 for update]; // update quo;
    – Teja
    Nov 28, 2013 at 7:13
  • i got the clear picture that i have to use the future method in trigger to get rid of this error.can i know how i can use future in this program
    – Teja
    Nov 28, 2013 at 7:15
  • There is no need to use an @future method to implement this. If my description of your trigger behavior is inaccurate, please edit your original question and add a description of what this trigger is supposed to do.
    – Mark Pond
    Nov 28, 2013 at 18:21
0

forgive me if i'm wrong since i'm a beginner. what I see is you are locking the record using For Update, while locking that record, no user is allowed to update that record. So I think this is what is happening with you since the very next line is

update quo;

try removing for update and see what happens

0

there are several things you need to reconsider and change inside your code

Why do you want this to work after insert - after update?

in the first loop because is an after trigger instead of looping all the records you can replace this:

Set<Id> quoteIds = new Set<Id>();
List<Quote__c> quotes = new List<Quote__c>();

for(Quote_Line_Item__c record: Trigger.new) {
    if (record.Quote1__c != null){
        quoteIds.add(record.Quote1__c);
    }
}

To this single line:

Map<Id, Quote__c> qIds_Quotes = [SELECT Id, Name FROM Quote_Line_Item__c WHERE Id IN: trigger.newMap.keySet() AND record.Quote1__c != null];

Then in your second loop you are making SOQL queries and DML statements:

 for(AggregateResult ar:[SELECT Quote1__c , SUM(Max_Batch__c)sumMax FROM Quote_Line_Item__c WHERE Quote1__c IN :quoteIds GROUP BY Quote1__c]) {
  Quote__C qu=new quote__c();
  qu.id=(Id)ar.get('Quote1__c');
  qu.Potential__c=(Decimal)ar.get('sumMax');
  quotes.add(qu);
  list<quote__c> quo = [select id,potential__c from quote__c where id IN :quotes limit 1 for update]; --SOQL query
  update quo; DML statement
}

Instead use this pattern:

//Create a new list outside for loop
list<quote__c> quo = new List<quote__c>();

//loop
for(AggregateResult ar:[SELECT Quote1__c , SUM(Max_Batch__c)sumMax FROM Quote_Line_Item__c WHERE Quote1__c IN :quoteIds GROUP BY Quote1__c]){
     //do other stuff here, create records, assign field values, etc
     quotes.add(createdRecord);
}

And do only one update outside the for loop, because you are using after context trigger, every update statement may cause your trigger to fire recursively and not to work how you expected, I really suggest you to rethink your code and maybe use the before context

Regards!

You must log in to answer this question.

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