+ Start a Discussion
BryanHartBryanHart 

Update an SObject without an ID

I've got an SObject that is given to me by a webservice, which I have to update.

Unfortunatly, this object doesn't have an ID because the external service that made the request doesn't have it.

 

I can easily query for the ID, however the ID field is not writable, so I can't just set the sobject's ID and the do an update.

I can't just query the object, then copy over all the fields because I don't know which fields the external service wants me to update (don't want to accidently null out fields).

 

What is the best way to do an update on an object where the ID is known, but is not in the SObject itself?

sornasorna

If you have an external Id field which would be primary key of your legacy system, then you can use that to do an upsert. But without Id or external Id you can't perform an update.

BryanHartBryanHart

Unfortunatly no external ID, since SF doesn't allow compound keys (the object can come from a few external systems, each with its own IDs).

 

I can query and get the existing record no problem, and I can copy fields into it and update it... but I don't know WHICH fields to copy. I don't want to copy them all because AFAIK there is no way to tell between a field being null and a field not being present (therefore not to be updated).

Any idea on how to do that?

Max_gMax_g

Consider adding a calculated external key to your incoming record that will then be available for the upsert method.

BryanHartBryanHart

That is a good idea, but unfortunatly it wont work for our product.

 

We have to do this for SocialPersona, Contact, Account and Lead.

Additionally, the way we match existing objects is configurable (match by firstname/lastname, match by externalId/provider, etc). We'd need multiple external ID formula fields that were based on non-required fields.

 

:(

sfdcfoxsfdcfox

Are you referring to the field being null in SFDC, or in your external app? Once you have the ID, you specify just the fields you want. Any fields not included in the object won't be updated. This is identical to how the UPDATE function works in SQL when providing a field list. If you're using the Partner WSDL, there's a fail-safe mechanism that requires you to null a field using fieldsToNull, so you can't accidentally wipe out a value to null. Your external apps that are querying the data should probably query all the fields they need, construct a separate copy of the record in memory, update just the values they need to, then save the copy back to the database.

BryanHartBryanHart

We're trying to insert a Case, Contact (or account or lead), SocialPersona and SocialPost objects at once, and there are a bunch of lookups between them.

The Contact/lead/account and Social Persona may already exist so we have to query to find the ID so we can update.

The case may already exist and may or may not be closed, so we need to query for that too.

We're blowing through the API limits by doing the above on the client.

Our data does not batch well (data comes in a steady flow, but customers expect low latency so we can't just send a batch once per hour or anything).

 

How would you recommend reducing the number of API calls we use?

 

We decided to use a web service so that we could use a single JSON object to send all the required information at once, and move the logic/queries to our app... but then we encountered the above problem where we couldnt set the ID on an SObject.

sfdcfoxsfdcfox

A WS call seems like the appropriate response here, but the question then becomes, is it he most efficient method possible? You'll have to weigh caching times versus API call limits, etc. Maybe you could make some of the pages use Visualforce, which admittedly have higher limits than webservice api calls. In fact, they use no API calls at all, because they're under a different governor completely. It might not help you, but it's worth a try.

BryanHartBryanHart

I'll look into it.

Right now we're looking into hacking the JSON that we get and injecting the ID...

or deserializing the sobjects as maps and then inserting the ID fields, serializing it again and deserializing it as the correct object.

 

not ideal, but after looking around, thats all I could find.