+ Start a Discussion
DaNae PetersonDaNae Peterson 

Incompatible key type

Hi all, 

We have a 3rd party app that moves all opportunities on a child account to the parent account every hour.  We do not want this to happen so I am trying to write an after update trigger that will move the opportunity back to the previous/child account.  I am running into trouble though with my code.  I am getting the following error: "Incompatible key type Opportunity for Map<Id,Opportunity>".  I am also getting the error "Variable o does not exist" -- I think one of my }s is off (both of these errors are happening on line 13).  Below is my code.  Can someone please look at it and figure out where I went wrong and shed some light on how to fix it? 

Thanks!


trigger SwitchBackAccount on Opportunity (after update) {
    
map<id,Opportunity> changeAcctId = new map<id,Opportunity>();
List<Opportunity> SROpps = new List<Opportunity>();
for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
changeAcctId.put(o.id,o);
}
}    
List<Opportunity> opps = [select Id, AccountId from Opportunity where Id in :changeAcctId.keyset()];
if(opps <> NULL && changeAcctId.size() > 0){
for(Opportunity op : opps){
op.AccountId = changeAcctId.get(o).AccountId;    
opps.add(op);
}       
update SROpps;
}

}
Best Answer chosen by DaNae Peterson
Shrikant BagalShrikant Bagal
Try following code:
 
trigger SwitchBackAccount on Opportunity (before update) {

for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
           o.AccountId =   trigger.oldmap.get(o.id).AccountId;       
}
}  
}

if its resolved your issue,please mark as best answer so it will help to other who will serve same problem.
​Thanks! 

All Answers

Shrikant BagalShrikant Bagal
hello Danae,

Please try following code:
 
trigger SwitchBackAccount on Opportunity (after update) {
    
map<id,Opportunity> changeAcctId = new map<id,Opportunity>();
List<Opportunity> SROpps = new List<Opportunity>();
for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
changeAcctId.put(o.id,o);
}
}    
List<Opportunity> opps = [select Id, AccountId from Opportunity where Id in :changeAcctId.keyset()];
if(opps <> NULL && changeAcctId.size() > 0){
for(Opportunity op : opps){
op.AccountId = changeAcctId.get(op.Id).AccountId;    
opps.add(op);
}       
update SROpps;
}

}

if its resolved your issue,please mark as best answer so it will help to other who will serve same problem.
​Thanks! 
DaNae PetersonDaNae Peterson
Thanks for such a quick response!  I am able to save the trigger without any errors but when I go to test the trigger, I am unable to save the opportunity due to the following error:

SwitchBackAccount: execution of AfterUpdate caused by: System.FinalException: Cannot modify a collection while it is being iterated.: Trigger.SwitchBackAccount: line 12, column 1

Any thoughts?
Shrikant BagalShrikant Bagal
As we cann't perform DMl operation on same Object on which trigger is written so please use following code:
 
trigger SwitchBackAccount on Opportunity (beforeupdate) {
    
map<id,Opportunity> changeAcctId = new map<id,Opportunity>();

for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
changeAcctId.put(o.id,o);
}
}    
List<Opportunity> opps = [select Id, AccountId from Opportunity where Id in :changeAcctId.keyset()];
if(opps <> NULL && changeAcctId.size() > 0){
for(Opportunity op : opps){
op.AccountId = changeAcctId.get(op.Id).AccountId;    

}       

}

}

if its resolved your issue,please mark as best answer so it will help to other who will serve same problem.
​Thanks! 
Shrikant BagalShrikant Bagal

As we cann't perform DMl operation on same Object on which trigger is written so please use following code:

 
trigger SwitchBackAccount on Opportunity (before update) {
    
map<id,Opportunity> changeAcctId = new map<id,Opportunity>();

for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
changeAcctId.put(o.id,o);
}
}    
List<Opportunity> opps = [select Id, AccountId from Opportunity where Id in :changeAcctId.keyset()];
if(opps <> NULL && changeAcctId.size() > 0){
for(Opportunity op : opps){
op.AccountId = changeAcctId.get(op.Id).AccountId;    

}       

}

}

if its resolved your issue,please mark as best answer so it will help to other who will serve same problem.
​Thanks! 

 
DaNae PetersonDaNae Peterson
I can save now without an error but it is not doing what I want it to (which is to switch the account field back to the child account).  I am thinking the problem stems from line 13...is changeAcctId.get(op.Id).AccountId referring to the old account Id (o in the first for loop)?
Shrikant BagalShrikant Bagal
Can you please describe your scenario?
DaNae PetersonDaNae Peterson
We have a 3rd party app that moves all opportunities located on child accounts to the parent account every hour.  We do not want this to happen though because there are instances where an opportunity needs to stay at the child account level.  As a result, I am trying to write a trigger that will move the opportunity back to the previous/child account.
Shrikant BagalShrikant Bagal
Try following code:
 
trigger SwitchBackAccount on Opportunity (before update) {

for(Opportunity o : trigger.new){
if(trigger.oldmap.get(o.id).AccountId != o.AccountId){
           o.AccountId =   trigger.oldmap.get(o.id).AccountId;       
}
}  
}

if its resolved your issue,please mark as best answer so it will help to other who will serve same problem.
​Thanks! 
This was selected as the best answer
DaNae PetersonDaNae Peterson
This worked like a charm, THANK YOU!!!!