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
Sudhir_MeruSudhir_Meru 

Update Multiple Objects in Trigger

Hi

  There are 3 Objects Asset, Contracts and Contract_Line_C 

Contract_Line_C is associated to ( Asset and Contracts) Below is a trigger I am writing to Update If Asset AccountId is update all its associated Contracts and its associted Assets AccountId must be updated. 

trigger Asset_Account_Update on Asset (After Update)
{

/* Set<Asset> Ast = New Set<Asset>([SELECT AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1]);
System.Debug('Asset AccountId = ' + Ast); */

Asset A;
A = [SELECT AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1 ];
System.Debug('Asset AccountId = ' + A.AccountId);

List<Contract_Lines__c> CL = [SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.AccountId ];

List<Contract> Cont = [SELECT Id,AccountId FROM Contract
                       WHERE Id in (SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.AccountId) ];

for( Contract UpdCont : Cont)
{
UpdCont.AccountId = A.AccountId;
Update UpdCont;  
}

/ *  This Part is not working need advise how to change.  */
List<Contract_Lines__c> CL2 = [SELECT Asset__c FROM Contract_Lines__c WHERE Contract__c in :Cont.Id ];

List<Asset> A2 = [SELECT Id,AccountId FROM Asset WHERE Asset__c in :CL2.Asset__c];

   for ( Asset Ast : A2)
    {
      Ast.AccountId = :AccountIDSet;
     }
     Update Ast;

}


I get unexpected token error. Please suggest me how to pass values from one list of SOQL to another and make update

Thanks
Sudhir
Best Answer chosen by Sudhir_Meru
CheyneCheyne
Sorry, the update outside of the loop should say update Ast1.

You're getting the maximum trigger depth error because your trigger is updating the same object that it is operating on. In other words, after you run update Ast1, the trigger is running again on the records that you just updated. You need to make sure that the Assets are not updated again the second time the trigger runs. For example, you could check that the AccountId is null before updating it. Example:

List<Asset> assetsToUpdate = new List<Asset>();
for (Asset Ast2 : Ast1) {
    if (Ast2.AccountId == null) {
        Ast2.AccountId = A.AccountId;
        assetsToUpdate.add(Ast2);
    }
}
update assetsToUpdate;

You could also use a static variable in a separate Apex class, as described here: http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US (http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US" target="_blank)

All Answers

CheyneCheyne
You cannot access the IDs of the lists of query results that way. You need to create a Set of IDs from the query result. 

Set<Id> contractIds = new Set<Id>();
for (Contract c : Cont) {
    contractIds.add(c.Id);
}
List<Contract_Lines__c> CL2 = [SELECT Asset__c FROM Contract_Lines__c WHERE Contract__c IN :contractIds];

And then do the same thing for the Asset query.
Ashish_SFDCAshish_SFDC

Hi Sudhir, 


Post the exact error also let us know on which line and which word the code is breaking. 

What is the relationship between Asset - Contract and Asset - Contract_Line_C. 


Regards,

Ashish

Sudhir_MeruSudhir_Meru
Hi Ashish, 

  I modified the code as mentioned below 


trigger Asset_Account_Update on Asset (After Update)
{

/* Set<Asset> Ast = New Set<Asset>([SELECT AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1]);
System.Debug('Asset AccountId = ' + Ast); */

Asset A;
A = [SELECT Id,AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1 ];
System.Debug('Asset AccountId = ' + A.AccountId);

List<Contract_Lines__c> CL = [SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id ];

List<Contract> Cont = [SELECT Id,AccountId FROM Contract
                       WHERE Id in (SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id) ];

for( Contract UpdCont : Cont)
{
UpdCont.AccountId = A.AccountId;
Update UpdCont;  
}
 

for ( Contract GetCon : Cont)
{
List<Contract_Lines__c> CL1 = [SELECT Asset__c FROM Contract_Lines__c WHERE Contract__c = :GetCon.Id ];

  for(Contract_Lines__c GetCL1 : CL1)
   {
     List<Asset> Ast1 = [SELECT Id,AccountId FROM Asset WHERE Id = :GetCL1.Asset__c];
   for ( Asset Ast2 : Ast1)
    {
      Ast2.AccountId = A.AccountId; 
      Update Ast2;   
    }    
   }
}

}

Below is the error I get from trigger

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger Asset_Account_Update caused an unexpected exception, contact your administrator: Asset_Account_Update: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 02i11000000EtKGAA0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Asset_Account_Update: maximum trigger depth exceeded Asset trigger event AfterUpdate for [02i11000000EOtJ] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG] Asset trigger event AfterUpdate for [02i11000000EtKG]: []: Trigger.Asset_Account_Update: line 34, column 1
Sudhir_MeruSudhir_Meru
Hi Cheyne,

   Tried your method it worked but the last Update is not happening 

trigger Asset_Account_Update on Asset (After Update)
{

Asset A;
A = [SELECT Id,AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1 ];
System.Debug('Asset AccountId = ' + A.AccountId);

List<Contract_Lines__c> CL = [SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id ];

List<Contract> Cont = [SELECT Id,AccountId FROM Contract
                       WHERE Id in (SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id) ];

for( Contract UpdCont : Cont)
{
UpdCont.AccountId = A.AccountId;
Update UpdCont;  
}

Set<Id> contractIds = new Set<Id>(); 
for (Contract c : Cont)
{
    contractIds.add(c.Id);
    system.debug('ContractId = ' + c.Id);
}

List<Contract_Lines__c> CL1 = [SELECT Asset__c FROM Contract_Lines__c WHERE Contract__c IN :contractIds];


Set<Id> contractlineIds = new Set<Id>();
for (Contract_Lines__c cntl : CL1)
{
    contractIds.add(cntl.Asset__c);
    system.debug('Child AssetId = ' + cntl.Asset__c);
}

List<Asset> Ast1 = [SELECT Id,AccountId FROM Asset WHERE Id = :contractlineIds ];

for ( Asset Ast2 : Ast1)
   {
   
    Ast2.AccountId = A.AccountId; 
    Update Ast2;   
    system.debug('Child Asset AccountId = ' +Ast2.AccountId);
    }    
 
}



CheyneCheyne
It doesn't look like you ever add anything to contractlineIds, so your Asset list is probably empty. Try this:

for (Contract_lines__c cntl : CL1) {
    contractlineIds.add(contl.Asset__c);
}

Also, you should move your update statement outside of the for loop, so that you don't run into the governor limit for DML statements. You can do this by changing the last part to

for (Asset Ast2 : Ast1) {
    Ast2.AccountId = A.AccountId;
}
update Ast2;


Sudhir_MeruSudhir_Meru
Hi Cheyne, 

 I am getting below error while updating from trigger

trigger Asset_Account_Update on Asset (After Update)
{

Asset A;
A = [SELECT Id,AccountId FROM Asset WHERE Id in :trigger.newmap.keyset() limit 1 ];
System.Debug('Asset AccountId = ' + A.AccountId);

List<Contract_Lines__c> CL = [SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id ];

List<Contract> Cont = [SELECT Id,AccountId FROM Contract
                       WHERE Id in (SELECT Contract__c FROM Contract_Lines__c WHERE Asset__c  = :A.Id) ];

for( Contract UpdCont : Cont)
{
UpdCont.AccountId = A.AccountId;
Update UpdCont;  
}

Set<Id> contractIds = new Set<Id>(); 
for (Contract c : Cont)
{
    contractIds.add(c.Id);
    system.debug('ContractId = ' + c.Id);
}

List<Contract_Lines__c> CL1 = [SELECT Asset__c FROM Contract_Lines__c WHERE Contract__c IN :contractIds];


Set<Id> contractlineIds = new Set<Id>();
for (Contract_Lines__c cntl : CL1)
{
    contractlineIds.add(cntl.Asset__c);
    system.debug('Child AssetId = ' + cntl.Asset__c);
}

List<Asset> Ast1 = [SELECT Id,AccountId FROM Asset WHERE Id = :contractlineIds ];

for ( Asset Ast2 : Ast1)
   {   
    Ast2.AccountId = A.AccountId;           
      Update Ast2;
    system.debug('Child Asset AccountId = ' +Ast2.AccountId);
    System.Debug('Asset AccountId = ' + A.AccountId);
    }
     
   
 
}


Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger Asset_Account_Update caused an unexpected exception, contact your administrator: Asset_Account_Update: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 02i11000000ENxRAAW; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Asset_Account_Update: maximum trigger depth exceeded Asset trigger event AfterUpdate for [02i11000000EOtJ] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR] Asset trigger event AfterUpdate for [02i11000000ENxR]: []: Trigger.Asset_Account_Update: line 41, column 1



Also While modified as you suggested 

for (Asset Ast2 : Ast1) {
    Ast2.AccountId = A.AccountId;
}
update Ast2;

adding update outside the loop i get below error. 

Error Error: Compile Error: Variable does not exist: Ast2 at line 45 column 12

Please suggest

Thanks
Sudhir
CheyneCheyne
Sorry, the update outside of the loop should say update Ast1.

You're getting the maximum trigger depth error because your trigger is updating the same object that it is operating on. In other words, after you run update Ast1, the trigger is running again on the records that you just updated. You need to make sure that the Assets are not updated again the second time the trigger runs. For example, you could check that the AccountId is null before updating it. Example:

List<Asset> assetsToUpdate = new List<Asset>();
for (Asset Ast2 : Ast1) {
    if (Ast2.AccountId == null) {
        Ast2.AccountId = A.AccountId;
        assetsToUpdate.add(Ast2);
    }
}
update assetsToUpdate;

You could also use a static variable in a separate Apex class, as described here: http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US (http://help.salesforce.com/apex/HTViewSolution?id=000133752&language=en_US" target="_blank)
This was selected as the best answer
Sudhir_MeruSudhir_Meru
Hi Cheyne

Thank You Very Much for your Help it worked as it has to work. Appriciate you Help Many Thanks

Thanks
Sudhir