Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Upsert with foreign key #34

Closed
paulchambers opened this Issue · 5 comments

4 participants

Paul Dan Diephouse thymulebot Mike Cantrell
Paul

Is it possible to upsert using foreign keys via the salesforce connector?

The SFDC API docs say:


You can use external ID fields as a foreign key, allowing you to access records in a single step instead of querying a record to get the ID first. To do this, specify the foreign key name and the external ID field value.

The following example upserts an Opportunity. The Opportunity references an Account. Rather than specify the account ID, which would require a separate query to obtain, we specify an external ID for the account, in this example the External_SAP1_ACCTID__c custom field.

public void upsertForeignKeySample()
{
  Opportunity upsertOpportunity = new Opportunity();
  upsertOpportunity.setStageName("Prospecting");
  //To indicate the reference, attach an Account object,
  //which has only the external ID field specified.
  Account upsertParentAccountRef = new Account();
  upsertParentAccountRef.setExternal_SAP1_ACCTID__c("SAP111111");
  upsertOpportunity.setAccount(upsertParentAccountRef);
  //Set the external ID for the Opportunity
  upsertOpportunity.set_SAP1_OPPID__c("SAP222222");
  UpsertResult[] upsertResults = binding.upsert("SAP1_OPPID__c",
            new SObject[] {upsertOpportunity});

I need to be able to upsert a Asset and reference a Account using a second ExternalID field on the Account. How should the payload map for this look?

This is a snippet of the mule config, the External ID field on the Account is called AccountExtId__c

<sfdc:upsert externalIdFieldName="AssetId__c" type="Asset" doc:name="Salesforce">
  <sfdc:objects ref="#[payload]" />
</sfdc:upsert>
Dan Diephouse
Collaborator

I think with Mule you would basically have a structure like this for the above example

Map upsertOpportunity = new HashMap();
upsertOpportunity.put("stageName", "Prospecting");
//To indicate the reference, attach an Account object,
//which has only the external ID field specified.
Map upsertParentAccountRef = new HashMap();
upsertParentAccountRef.put("External_SAP1_ACCTID__c", "SAP111111");
upsertOpportunity.put("account", upsertParentAccountRef);
//Set the external ID for the Opportunity
upsertOpportunity.put("SAP1_OPPID__c", "SAP222222");

Paul

I have tried that structure and the inner hashmap is not converted to a SObject.

Looking at org.mule.modules.salesforce.toSObjectList it does not convert a nested HashMap into a SObject, I also don't see how it would know what type to use for the nested SObject.

INFO  2012-04-11 08:56:53,257 [[ax2sf].HTTP.receiver.02] org.mule.api.processor.LoggerMessageProcessor: [{stageName=Prospecting, account={SAP1_OPPID_c=SAP222222}, ExternalSAP1_ACCTIDc=SAP111111}]
ERROR 2012-04-11 08:56:53,460 [[ax2sf].HTTP.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy: 
********************************************************************************
Message               : Failed to invoke upsert. Message payload is of type: ArrayList
Code                  : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. Unable to find xml type for :java.util.HashMap (java.io.IOException)
  com.sforce.ws.bind.XmlObject:241 (null)
2. Failed to send request to https://cs4-api.salesforce.com/services/Soap/u/23.0/XXXXXXXXXXXX
(com.sforce.ws.ConnectionException)
  com.sforce.ws.transport.SoapConnection:124 (null)
3. Failed to invoke upsert. Message payload is of type: ArrayList (org.mule.api.MessagingException)
  org.mule.modules.salesforce.config.UpsertMessageProcessor:518 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.io.IOException: Unable to find xml type for :java.util.HashMap
    at com.sforce.ws.bind.XmlObject.write(XmlObject.java:241)
    at com.sforce.ws.bind.XmlObject.write(XmlObject.java:228)
    at com.sforce.ws.bind.TypeMapper.writeSingleObject(TypeMapper.java:352)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

Paul

I have been able to work around this by using a transformer to create the Account SObject before passing the array to the connector.

thymulebot

The fix will be available in the nex beta release, Thank you.

Mike Cantrell

This doesn't appear to be fixed yet. Please review the above pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.