14

Question

I know that it is possible to update a generic of List<SObject>, But what is the best approach to generate that list without knowing the SObjectType, only the ids ?

Sample:

 List<SObject> l = new List<SObject>();
 
 SObject o1 = new SObject(id='xxxxxx'); //this Id could be an Account
 o1.Name = 'Test';
 l.add(o1);


 SObject o2 = new SObject(id='xxxxxx'); //this Id could be a Custom
 o2.Name = 'Test' 
 l.add(o2); 
 
 //this is possible
 update l;

Unfortunately, SObject constructor doesn't allow id as parameter.

Backgound:

I'm trying to make a generic WS which will receive a list of objects to update( or upsert). The received object could by any type.

WS Request sample:

  [
   {id:'xxxxx',Name:'Test'},
   {id:'yyyyy',Name:'Test 2'},
   {id:'zzzzz',Name:'Test 3'}
  ]

The id attribute cloud be from any SObject.( I know the extra attr to update always exist).

Thanks in advance for your time.

4
  • What exactly is the web service receiving?
    – Mike Chale
    Oct 9, 2013 at 18:36
  • @MikeChale I've updated my question adding a request sample Oct 9, 2013 at 18:43
  • Couldnt you use the ID key prefix to determine what the type of SObject was? Oct 9, 2013 at 19:12
  • I though so, looks like @amatorVitae used this prefix method. Beat me to typing it out lol Oct 9, 2013 at 19:14

2 Answers 2

24

Once you have the sObjectType you should be able to construct the sObject instance using the sObjectType.newSObject(ID Id) method. You can get the sObjectType from the Id using the Id.getSObjectType() method;

Map<Id, String> idsToUpdate = new Map<Id, String>();

// Put the Id's and associated name values in the map

List<SObject> sObjectsToUpdate = new List<SObject>();

for (Id idToUpdate : idsToUpdate.keySet()) {
    SObject o1 = idToUpdate.getSObjectType().newSObject(idToUpdate);
    // Set the Name field dynamically
    o1.put('Name', idsToUpdate.get(idToUpdate));
    sObjectsToUpdate.add(o1);
}

update sObjectsToUpdate;
3
  • Incredible answer, This is exactly what I was looking for. Oct 9, 2013 at 22:21
  • When I try this sample code, I'm getting Variable does not exist: Name. Have any idea why?
    – Brane
    Oct 8, 2018 at 12:57
  • @user3850805 I've changed the code to use a dynamic put to set the Name field. Oct 8, 2018 at 20:29
5

Here's a link to a post that I think answers your question: Infering sObject Type from Id or collection of Id's

Essentially, the solution entails:

  1. Pulling the sObject "prefix" (the first 3 characters) from the id you receive
  2. Get the sObjectType so you can cast your objects as the corresponding sObject (or list<yourSobject__c>)
  3. Upsert the typed-records

Link to SF Docs


Here's a Utility Method I wrote that writes a query to select ALL fields from an sObject by only giving the string value of the Object Name. It exemplifies finding an sObject's metadata (in this case, its fields).

public static string FormatFieldsForQuery(string objectName,string prefix){
    if(string.isNotBlank(prefix)){
        if(prefix.endsWith('__c'))
            prefix=prefix.replace('__c','__r.');   
        if(!prefix.endsWith('.'))
            prefix+='.';
    }
    string fields = '';
    sObjectType objectType=Schema.getGlobalDescribe().get(objectName);
    if(objectType==null)
        return fields;
    for(string f :objectType.getDescribe().fields.getMap().keySet())
        fields+=prefix+f+',';
    return fields.removeEnd(',');  
}//END FormatFieldsForQuery(string objectName,string prefix)
3
  • Based on @DanielBallinger comment , your answer and @ca_peterson answer, I think this is possible: Sobject o1 = Schema.getGlobalDescribe().get(myId.getSObjectType().getDescribe().getName()).newSObject(myId); , isn't ?.... One line will solve my problem, sounds awsome Oct 9, 2013 at 19:34
  • @MartinBorthiry Sorry, I deleted my comment as I wanted to expand on it as a separate answer. IMHO amatorVitae still deserves the credit for getting the answer. Oct 9, 2013 at 19:41
  • @amatorVitae thanks for this approach, It was the base for the best solution. My up vote here Oct 9, 2013 at 22:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .