[SalesForce] Got DUPLICATE_VALUE exception with value : and record id: in a batch

I got the following exception on a batch job:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: <unknown> duplicates value on record with id: <unknown>

It fails SOMETIMES when inserting AccountShare objects.

    // Delete existing shares for these accts/users
    Set<ID> acctIDs = new Set<ID>(salesRelColl.getAccountIDs());
    Set<ID> userIDs = new Set<ID>(salesRelColl.getUserIDs());
    EntitlementManager.deleteSharePermissionsForAccounts(acctIDs, userIDs);
    String relatedListsAccessLevel = EntitlementManager.ACCESS_LEVEL_EDIT;
    Map<ID,Set<ID>> acctUserMapForCptyShares = new Map<ID,Set<ID>>();

    List<AccountShare> shares = new List<AccountShare>();
    List<AccountShare> sharesOwner = new List<AccountShare>();

    List<Id> accountIDs = new List<Id>();
    Map<Id, Account> accountOwnerMap = new Map<Id,Account>();

    for ( Sales_Relationship__c salesRel : salesRelColl.getList() )
    {
      accountIDs.add(salesRel.Account__c);
    }

    AccountSelector accountSel = new AccountSelector();
    AccountCollection accountCol = accountSel.whereIDIn(accountIDs).execute();

    for(Account acct : accountCol.getList())
    {
      accountOwnerMap.put(acct.Id,acct);
    }

    for ( Sales_Relationship__c salesRel : salesRelColl.getList() )
    {

      ID userID = salesRel.Employee__r.User__c;
      if ( userID == null )
      {
        continue;
      }
      // exclude any non-current
      if ( !salesRel.Current__c )
      {
        continue;
      }

      if (accountOwnerMap.get(salesRel.Account__c) != null)
      {
        if (accountOwnerMap.get(salesRel.Account__c).OwnerId != userID)
        {
          ID acctID = salesRel.Account__c;
          String groupType = ROW_CAUSE_SALESPERSON;
          ID parentID = acctID;
          ID userOrGroupID = userID;
          String accessLevel = EntitlementManager.ACCESS_LEVEL_EDIT;
          String rowCause = groupType;

          AccountShare share = EntitlementManager.buildShareForAccount(parentID,
                    userOrGroupID,accessLevel,
                    relatedListsAccessLevel,
                    rowCause,groupType);

          shares.add(share);

          if ( !acctUserMapForCptyShares.containsKey(acctID) )
          {
            acctUserMapForCptyShares.put(acctID,new Set<ID>());
          }
          acctUserMapForCptyShares.get(acctID).add(userID);
        }
        else
        {
          AccountShare share = EntitlementManager.buildShareForAccount(salesRel.Account__c,userID,EntitlementManager.ACCESS_LEVEL_EDIT,
                    relatedListsAccessLevel,
                    ROW_CAUSE_SALESPERSON,ROW_CAUSE_SALESPERSON);
          sharesOwner.add(share);
        }
      }
    }

    if ( shares.size() > 0 )
    {
      // FAILS HERE
      insert shares;

    }

The fact that is something that does not happen all the time had made this bug not easy to reproduce.

Best Answer

Found the issue, with some help from @eyescream in the chatroom.

After some detective work I've found that this is caused by 2 batches trying to insert the same Share at the same time.

Even one of the jobs fail, the other continues and creates the share.

To be sure he suggested to use Database.insert(shares,false), which continues inserting all values from the shares list even if one of them fails.

Related Topic