9

This question is an extension to Write a generic JSON-serializable Parameters class without hitting “Apex Type unsupported in JSON: Object” where I learned how to serialize a Map to and from JSON.

My problem now is, that I also want to store SObjects as map values and always get a

System.TypeException: Invalid conversion from runtime type MAP<String,ANY> to SOBJECT:Account

in the last line of this snippet:

Map<String, Object> parameters = new Map<String, Object>();
Account acme = new Account(Name = 'Acme Corp.');
insert acme;
parameters.put('SObject', acme);
String serialized = JSON.serialize(parameters);
parameters = (Map<String, Object>) JSON.deserializeUntyped(serialized);
Account restoredAcme = (Account) parameters.get('SObject');

2 Answers 2

7

Try adding this instead of your last line of code:

String jsonstr = (String)JSON.serialize(parameters.get('SObject'));
SObject restoredAcme = (Account)JSON.deserialize(jsonstr, Account.class);

The problem with what you're currently trying to do is that you're essentially trying to cast a Map to an Account - which as you've seen, you cannot do.

As a workaround, you can serialize the Map to String and then deserialize that String to an Account.

4
  • That basically means you cannot serialize/deserialize a map with Objects AND SObjects to JSON, right?! So to store an SObject in a Map<String, Object> I first have to serialize it to a String, store it, deserialize as String and the deserialize with a concrete Type. Commented Nov 19, 2013 at 10:08
  • So the explanation is that the first deserialize creates a map for the Object (which sObject type basically is, a bunch of key-value entries) and then you need to remap it to the proper sObject. Makes sense actually.
    – zdropic
    Commented Nov 19, 2013 at 10:11
  • Btw, to make it generic, you can deserialize the jsonstr to sobject.class and then cast somewhere outside.
    – zdropic
    Commented Nov 19, 2013 at 10:15
  • I think you can serialize/deserialize a map with Objects AND SObjects - you just need to know the type to deserialize as (remember a Map<String,Object> is not an SObject hence the serialization to string first). Maybe you can expand on your question if there is more too it? Commented Nov 19, 2013 at 10:30
3

If you change your code to the code below the deserialize step will create a Map instance. The JSON parser cannot deserialize to a common object, it does understand how to construct an SObject.

Regards,

Leon

Map<String, SObject> parameters = new Map<String, SObject>();
Account acme = new Account(Name = 'Acme Corp.');
insert acme;
parameters.put('SObject', acme);
String serialized = JSON.serialize(parameters);
parameters = (Map<String, SObject>) JSON.deserialize(serialized, Map<String, SObject>.class);
Account restoredAcme = (Account) parameters.get('SObject');
System.debug(LoggingLevel.INFO, 'Restored acme name: ' + restoredAcme.name );

You must log in to answer this question.

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