0

So I'm receiving some Accounts from an external source. They could be exactly the ones I already have on the org but this external ones also have some custom Ids that I need to assign to the old ones.

I'm trying to achive this with an After Insert trigger:
-> get the Accounts that have the same Email as the new ones
-> get the data from the new ones and assign to the old ones
-> delete the new ones and update the old ones.

Trigger:

trigger AccountEmail on Account (after insert) {
//List<Account> Emails = [Select PersonEmail from Account];

List<Account> ToUpdate = new List<Account>();
List<Id> ToDelete = new List<Id>();
Map<String,Account> newAccs = new Map<String,Account>();
if(Trigger.isAfter) {
    for(Account a : Trigger.New) {
        if(a.some_Id__c != null && a.some_Id__c > 0) {
            newAccs.put(a.PersonEmail,a);
        }
    }


    for(Account oldAcc : [Select Id,PersonEmail,some_Id__c from Account where PersonEmail IN: newAccs.keySet()]) {
        if(oldAcc.some_Id__c == null) {
            Account d = newAccs.get(oldAcc.PersonEmail);
            oldAcc.some_Id__c = d.some_Id__c ;
            ToUpdate.add(oldAcc);
            ToDelete.add(d.id);
        }
    }
}

delete [select Id from Account where Id IN: ToDelete];
update ToUpdate; }  

And my test class:

 @isTest
public class AccountEmailDupeTest {
    @IsTest//(SeeAllData=true)
    static void testAccDupePreventer() {

      Account a1 = new Account(LastName='Test1', 
                            PersonEmail='[email protected]');
      Account a2 = new Account(LastName='Test2', 
                            PersonEmail='[email protected]');
      Account a3 = new Account(LastName='Test3', 
                            PersonEmail='[email protected]');
      Account[] accs = new Account[] {a1, a2, a3};
      insert accs;

      a2.PersonEmail = '[email protected]';
      a3.PersonEmail = '[email protected]';
      update accs;  

      Account dup1 = new Account(LastName='Test1Dup',
                                PersonEmail='[email protected]',
                                some_Id__c = 123);
      try {
         insert dup1;
      } catch (DmlException e) {
         system.debug('***ex:' + e.getMessage());
      }
      List<Account> t = [Select LastName, PersonEmail, some_Id__c from Account where some_Id__c = 123];
      system.debug('***t:' + t);

      Account dup2 = dup1;
      dup2.some_Id__c = 333;
      try {
         insert dup2;
      } catch (DmlException e) {
         system.debug('***ex:' + e.getMessage());
      }
    }
}  

On insert dup1 all works good and the first select returns the expected result but on the second insert I get: Insert failed. First exception on row 0 with id 001b000002LPfNWAA1; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]

Any solutions to this? Much appreciated!

EDIT: I get this on production:
First error: Upsert failed. First exception on row 3; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, namespace.AccountEmail: execution of AfterInsert

caused by: System.DmlException: Update failed. First exception on row 1 with id 001U00000...

1 Answer 1

2

You can see your code once you inserted dup1

insert dup1; // now it has id

If you assign dup1 to dup2

Account dup2 = dup1;

Then dup2 having same id/record. so you can't perform insert on dup2

what you need to do you can clone dup1 or create new account instance

instead of Account dup2 = dup1; use like below

 Account dup2 = dup1.clone();

or

Account dup2 = new Account(name='test');
1
  • Yup, it worked perfectly fine. Though I've had problems with the trigger on a production org and received the same error (not the test class but the real thing). I'll put this in prod and see if it's a go, if it is, I'll mark you as best answer. Thanks!
    – stefan
    Commented Dec 2, 2015 at 17:28

You must log in to answer this question.

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