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
EJWEJW 

Bug? Can't create a Map<Id, sObject> from a List<sObject>.

According to the documentation you should be able to create a map of Id or String to SObject from a list of sObjects and Database.query() returns a list of sObjects.   However, the following code will not compile/execute:

Map<Id, sObject> accounts = new Map<Id, sObject>( Database.query( 'SELECT Id FROM Account LIMIT 5' ) );

Also, map.putAll() should work similarly but gives the same error message.   Example of broken code:

Map<Id, sObject> accounts = new Map<Id, sObject>();
accounts.putAll( Database.query( 'SELECT Id FROM Account LIMIT 5' ) );

It looks like the map constructor and putall are expecting a list of explicit object types, not generic sObjects.  According to the documentation, a generic sObject list should work.

See the definition of Map.putAll() here:

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_map.htm

It states:

If the map is of IDs or Strings to sObjects, adds the list of sObject records l to the map in the same way as the Map constructor with this input.

 

Actually, with further testing it doesn't appear that I can get putAll() to work at all on a map of Id to sObject whether the input is a list of explicit types (say List<Account> ) or a list of sObjects.

Best Answer chosen by Admin (Salesforce Developers) 
rungerrunger

Hey, I just got pointed to this thread. It's a bug, and I'll try to get it addressed in the next major release.

All Answers

ciccic

As you've found, you can't make a list or map of a generic sobject, only of a specific one.  What does work is:-

 

Map<Id, sObject> accounts = new Map<Id, Account>(  (List<Account>) Database.query( 'SELECT Id FROM Account LIMIT 5' ) );

 

So you need to know what object you are making.

 

This makes generic code libs to handle sobjects quite tricky.  You can get the using code to pass in an empty list or map when you construct or use the generic code, but the generic code can't make lists or maps itself.

EJWEJW

As of Spring '10 (and the org I'm working in has been upgraded) you can now create Lists, Sets and Maps of generic sObjects.  For example, to achieve what I've wanted I'm successfully using code like the following, though it's not ideal:

 

Map<Id, sObject> accounts = new Map<Id, sObject> ();

for ( sObject account : [SELECT Id FROM Account LIMIT 5] )

 accounts.put( account.id, account );

 

Thanks, 

ciccic
I hadn't noticed that in Spring 10.  Often those little things that sneak into a release are the most useful...  Will have to rewrite my generics libs.
ForceMantis (Amit Jain)ForceMantis (Amit Jain)

I was also facing this issue while I came across this thread. I agree with reply posted by 'cic'.

 

We can't make a map of Id to sobject using a list of sobjects. If we know the object name this works as suggested by 'cic'.

rungerrunger

Hey, I just got pointed to this thread. It's a bug, and I'll try to get it addressed in the next major release.

This was selected as the best answer
craigmhcraigmh

I believe Microsoft calls this an "unexpected product development that has been omitted from the documentation." :)

EJWEJW

runger wrote:

Hey, I just got pointed to this thread. It's a bug, and I'll try to get it addressed in the next major release.


Glad to hear it, thanks.  Anything that saves script statements makes me happy. :)

Rakesh BoddepalliRakesh Boddepalli

Was this ever got fixed ?

EJWEJW
Yes, it's fixed.
NawshineNawshine

Still can't get mine to work
 

map<Id,list<sObject>> objRecordsMap = new map<Id,list<sObject>>();

objRecordsMap.putAll(Database.query(selectStatement));

 

Any clues?

EJWEJW

Nawshine wrote:

Still can't get mine to work
 

map<Id,list<sObject>> objRecordsMap = new map<Id,list<sObject>>();

objRecordsMap.putAll(Database.query(selectStatement));

 

Any clues?


You're trying to load that into a map of Id to List<sObject> and it needs to be a map of Id to sObject (not a list of them per Id).  So your example should be like this:

 

Map<Id, sObject> objRecordsMap = new Map<Id, sObject>();
objRecordsMap.putAll( Database.query( selectStatement ) );

// Alternatively, you could do this I believe:

Map<Id, sObject> objRecordsMap = new Map<Id, sObject>( Database.query( selectStatement ) );

 

Thanks,

NawshineNawshine
Yess!! of course! Thanks for your prompt reply!