Find your content:

Search form

You are here

Salesforce merge functionality

 
Share

I have an issue where my my org is uploading a ton of leads at a time via the dataloader. These new leads could potentially be existing accounts / leads and need to be merged to their latest associated record.

The issue I'm having is, imagine a batch of 200 records hits my trigger and all have to be merged with older leads. Only 150 DML statements are allowed, and each merge has to be done one at a time which causes an issue.

I know the Salesforce API has an object called MergeRequest which allows you to do a collection of merges within a single call.

Has anyone been able to figure out an efficient way of achieving this? Also, does anyone know if the API can be called within a trigger / apex?


Attribution to: Double A

Possible Suggestion/Solution #1

Not the right solution by any means but have you considered just reducing the size of the batch within the data loader (Settings->Options)?enter image description here


Attribution to: Joel Mansford

Possible Suggestion/Solution #2

Instead of using merge(), I would just perform the transaction with bulkable methods, like update and delete.

Your trigger will collect all the email addresses, names, or whatever you need to match on, and query for the matching records. Then update important fields on the old record and either delete or keep the new Lead record, maybe with a Status = 'Inactive' or something. If it's properly bulkified, it requires only one DML and 2 queries per batch.


Attribution to: Jeremy Nottingham

Possible Suggestion/Solution #3

Yes, you can call the SOAP API from Apex, although the process is not well documented. And you can use the API to merge via MergeRequest object; I've just tested it.

First, you'll need to export the Partner WSDL (Setup->Develop->API) and then import it to create Apex classes (Setup->Develop->Apex Classes->Generate From WSDL). The good news is that whereas previously, you couldn't import the WSDL directly (due to naming conflicts), that seems to be fixed; the importer automatically appends _x to problematic names, so (for example) merge becomes merge_x.

When you import the WSDL, you'll have to choose names for the generated Apex classes (one per namespace), for my example code below, I chose class names as follows:

  • urn:sobject.partner.soap.sforce.com -> PartnerSObject
  • urn:fault.partner.soap.sforce.com -> PartnerAPIFaults
  • urn:partner.soap.sforce.com -> PartnerAPI

You will also need to add your salesforce server to the remote site settings to allow soap callouts.

With those preliminaries out of the way, here's some basic code to prove it works. I didn't write it as a test class as I was working with the code iteratively in the Developer Console, and checking the log after each run. To test in your org, make sure you create accounts named "Merge Test A" and "Merge Test B". For extra proof, create a contact on account B, so you can see it reparented to Account A.

public class SoapMergeTest{

    public static void DoMerge() {
        Account AcctA = [select id, name from Account where name = 'Merge Test A'];
        Account AcctB = [select id, name from Account where name = 'Merge Test B'];

        //use current session instead of logging in.  
        //Will need to update enpoint as well (Login method normally handles this)        
        PartnerAPI.Soap soap = new PartnerAPI.Soap();
        //TODO: make this more robust, instead of hardcoding login url
        soap.endpoint_x = soap.endpoint_x.replace('login.salesforce.com', URL.getSalesforceBaseUrl().getHost());
        PartnerAPI.SessionHeader_element sessionHeader = new PartnerAPI.SessionHeader_element();
        sessionHeader.sessionId = UserInfo.getSessionId();
        soap.SessionHeader = sessionHeader;

        PartnerAPI.MergeRequest mrq = new PartnerAPI.MergeRequest();
        PartnerSObject.sObject_x objA = new PartnerSObject.sObject_x();
        objA.id = AcctA.id;
        objA.type_x = 'Account';
        mrq.masterRecord = objA;

        mrq.recordToMergeIds = new list<String>{AcctB.id};

        list<PartnerAPI.MergeResult> results = soap.merge_x(new list<PartnerAPI.MergeRequest>{mrq});
        system.debug('Merge Result: ' + results);

    }

}

Attribution to: Jason Clark

Possible Suggestion/Solution #4

We are testing this app at work:

http://www.ringlead.com/salesforce-applications/unique-upload/

Early in the process but the initial impression is positive. DupeBlocker markets an app which is similar.


Attribution to: MMcNamara
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/1164

My Block Status

My Block Content