8

I am pretty new with Salesforce and I am doing an integration where I have to update Salesforce with data from a Business System. I have a problem when trying to create new records in an object with lookup fields from another parent object. I am using java soap protocol with a partner connection and the field I am trying to update is of Master-Detail type. I can update it successfully if I enter the Salesforce ID for the value, but not when I enter the actual value that should go in the field.

In my example I want to update a store lookup field with a parent Account/store.

Example for Store: 7241

This does not work:

record.setField("Customer_Store__c","7241"); //Using the actual Store number
records[0] = record;
com.sforce.soap.partner.SaveResult[] results = partnerConnection.create(records);

This works:

record.setField("Customer_Store__c","001N0000007MJLO"); //Using the Salesforce ID
records[0] = record;
com.sforce.soap.partner.SaveResult[] results = partnerConnection.create(records);

However, I do not have the ID for the stores, unless I create a cross reference table somewhere, but I prefer not to. I was reading some posts online about creating relationships between the parent and child objects, but it appeared you had to create a new parent object simultaneously to get the parent object ID for the child objects. In my case the stores are already created and I only want to add records which has a relation to that store.

Does anyone know what the best practice is for this?
Maybe even have a code sample, which would be great.

Many Thanks in advance

8

You need to leverage an External ID field type on your Store object for the Store Number. This will allow the platform to automatically cross reference for you and avoid you needing to pre-query the Store records to obtained the Id's you need. The Salesforce API documentation goes into more details here.

You can use external ID fields as a foreign key, which allows you to create a record and relate it to another existing record in a single step instead of querying the parent record ID first. To do this, set the foreign key field to an instance of the parent sObject that only has the external ID field specified. This external ID should match the external ID value on the parent record.

The documentation in the link above is excellent and very detailed, so well worth a read, however the example code appears is based on the Enterprise WSDL, not the Partner WSDL. However the same principles applies to both, the Partner API is less type safe version.

Here is a Partner API version in Java (using the Salesforce WSC you appear to be using). In my case my parent object is Test and my child object is Test_Child. I have created a StoreNumber External Id field on my Test object and populated an existing record with the value 1234. Note also the use of the __r suffix when making the association between the child and parent (the field name is the same).

    SObject parentRef = new SObject();
    parentRef.setType("Test__c");
    parentRef.setField("StoreNumber__c", "1234");

    SObject childRecord = new SObject();
    childRecord.setType("Test_Child__c");
    childRecord.setField("Name", "Child Record");
    childRecord.setField("Test__r", parentRef);
    SObject[] records = new SObject[] { childRecord };        
    com.sforce.soap.partner.SaveResult[] results = connection.create(records);

Here is what my Store Number, External ID field looks like, note the External ID checkbox.

enter image description here

  • Thanks Andrew for the very detailed answer. I have tried it and the only issue I am having is with the Test__r field. In my case the parent ref type is "Account", with a custom field for Store_ID (which I have changed to be an Ext Id). Howevever, when I use Account__r as you illustrated I get a "No such column 'Account__r on entity <MyChildRec>__c" exception. Do I need to create this column or association somehow in MyChildRec__c object? – Kent Oct 7 '13 at 23:25
  • I managed to find out what the issue was. I had to set the reference (__r) on the field in my child object that I wanted to reference to the field in the parent. Maybe that was what you meant and just happened to call the parent object Test as well as the field in you child object the same? Anyway, many many thanks. – Kent Oct 8 '13 at 0:34
  • Ah yes, by default Lookup fields default their names to the name of the object the point to, so yes my parent object and field on the child pointing to it where both called Test__c, sorry for the confusion, glad you sorted it in the end! :) – Andrew Fawcett Oct 8 '13 at 7:36
1

There are several ways you can accomplish this goal.

Query, then Insert

Using this method, you double up your API usage by first querying for the store by number, then using the ID value you get back. For performance, you might consider caching the query results for some period of time, assuming that the store number is not likely to change frequently. Unless you're worried about your API usage, this would be the standard means of reaching your goal.

Triggers

In this scenario, you have a second field that accepts a store number, and a trigger on the server performs a query on insert, populating the lookup for you. This isn't more than a dozen lines of code, and would be simple to deploy and easy to maintain.

Custom Web Services

Using Apex Code, you can create a method that can be called directly from your code by downloading the WSDL into your project. This could accept all the necessary data, perform the translation of store number into an ID, etc, and insert the data. This is probably the most elaborate (time-consuming) path.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.