function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Upsert List of Generic sObjects

So what I am trying to accomplish is to upsert  List<sObject> with a field specification of what the external Id is. However this is the error message I get back when I try to save the class.


List<sObject> newlist = new List<sObject>();


upsert newlist ext_Id__c; (Error Msg: "Upsert with a field specification requires a concrete sObject type)



Any idea of a way around this?




Content removed.


Thanks for the reply but that did not work.


You need a way of getting real objects rather than sObjects. I did this recently but required some work. Basically, I had a bunch of wrappers extending a parent wrapper class, each wrapper implemented a toObject() method that returned the object i.e. a AccountWrapper would return an Account, ContactWrapper returned a Contact etc.


My method would take a list of the parent wrapper class, loop over each of the items in the list, call the toObject method and store it in a list of sObject - although the list was List<sObject>, the objects within them were "concrete" objects i.e. Accounts, Contacts etc


It may be possible to use Sobject describe information and an if statement; each branch would convert the list to a list of the real objects which could then be inserted.


Hope that gets the ball rolling.





I understand what you mean and i think that I am  doing that now. I the items that I am putting into the list of sObjects are definitley concrete. But i still cannot upsert the list using a field specification in order to decide whether to update or insert a certain item. Any other ideas or sample code you (or someone else) could share with me?


Do you have to make a wrapper for each object? Would that also mean you would have to make a wrapper for each custom object?


Yes, I made a wrapper for each object I wanted to use a generic upsert method. My circumstances were a little different - I had a visualforce page where users entered data in different parts of the page and these would map to different objects. The wrapper was a nice way of iterating over any objects from the database in the page as well as helping with a generic inserting/updating method.


I'm not sure what the error you're encountering at the moment is - are you still getting the "concrete" error message or something else?


My error message is that since I want to specify which field to check for existing external id's upsert. I cant specify the field specification without it being a concrete sObject.


Could you share some of the code? Might make it easier to see what the problem is.


The code is pretty much how my first post is.


You cannot do DML on a List<sobject>.  The list must be declared as a list of a concrete sobject type (e.g. List<foo__c>).



RJ PalomboRJ Palombo

Now that some time has lapsed since this post, is there anyway to achieve this now?

I don't think so.
James (CloudAnswers)James (CloudAnswers)

Adding my name to the list of people that would find this incredibly helpful as part of partner applications.

Sumitsing Ingle 15Sumitsing Ingle 15

When you will try to upsert a list of sObject  it might give an error like "DML on generic List only allowed for insert, update or delete". To resolve this problem you will need to separate out your list into two lists for insert and update.

Following is the code for the same :     
        //This is the list of sObject you want to upsert
       //List<sObject> yourList= new List<sObject>();

        List<sObject> lstRecordToInsert =  new List<sObject>();
        List<sObject> lstRecordToUpdate =  new List<sObject>();  
        for(sObject obj : yourList){
            if(obj.Id != null)
        if( !lstRecordToUpdate.isEmpty() )
            update lstRecordToUpdate;
        if( !lstRecordToInsert.isEmpty() )
            insert lstRecordToInsert;

I hope this might be helpful......

Oscar Murillo 10Oscar Murillo 10
Excellent...that's worked perfect!