0

I am trying to build a picklist which would display all the available SObject, and global describe returns me some strange SObject Address, when I try to instantiate dynamically this SObject, it fails with an error

System.TypeException: Invalid conversion from runtime type System.Address to SObject

, which is confusing me. Is an Address a SObject or a Compound Field? If this is System.Address compound field why then it is returned in the list of available SObjects by the global describe and describe Objects method?

String addressSObjectName = Schema.describeSObjects(new List<String>{'Address'})[0].getName();
System.debug(addressSObjectName);
DescribeSObjectResult objectDescribe = ((SObject)Type.forName(addressSObjectName).newInstance()).getSObjectType().getDescribe();

The similar issue happens with Location.

String location = Schema.describeSObjects(new List<String>{'Location'})[0].getName();
System.debug(location);
DescribeSObjectResult objectDescribe = ((SObject)Type.forName(location).newInstance()).getSObjectType().getDescribe();

and the error is in this case

System.TypeException: Invalid conversion from runtime type System.Location to SObject

2 Answers 2

1

Actually Address and Location are both Compound Fields (System.Address, System.Location) and a SObject (Schema.Address, Schema.Location). These SObjects are used for Field Service Lightning.

I have missed some small note in the bottom of the documentation page

“Address” in Salesforce can also refer to the Address compound field found on many standard objects. When referencing the Address object in your Apex code, always use Schema.Address instead of Address to prevent confusion with the standard Address compound field. If referencing both the address object and the Address field in the same snippet, you can differentiate between the two by using System.Address for the field and Schema.Address for the object.

enter image description here

The same note is present in the documentation of Compound Field Address https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_system_Address.htm#apex_class_system_Address

“Address” in Salesforce can also refer to the Address standard object. When referencing the Address object in your Apex code, always use Schema.Address instead of Address to prevent confusion with the standard Address compound field. If referencing both the Address object and the Address standard field in the same snippet, you can differentiate between the two by using System.Address for the field and Schema.Address for the object.

enter image description here

So to fix this error, it is possible just to add 'Schema.' prefix to the passed name of an object.

String addressSObjectName = Schema.describeSObjects(new List<String>{'Address'})[0].getName();
System.debug(addressSObjectName);
DescribeSObjectResult objectDescribe = ((SObject)Type.forName('Schema.' + addressSObjectName).newInstance()).getSObjectType().getDescribe();

The similar note in located in the bottom of the documentation page for Location

“Location” in Salesforce can also refer to the geolocation compound field found on many standard objects. When referencing the Location object in your Apex code, always use Schema.Location instead of Location to prevent confusion with the standard Location compound field. If referencing both the Location object and the Location field in the same snippet, you can differentiate between the two by using System.Location for the field and Schema.Location for the object.

enter image description here

and in the documentation of Location Compount Field

“Location” in Salesforce can also refer to the Location standard object. When referencing the Location object in your Apex code, always use Schema.Location instead of Location to prevent confusion with the standard Location compound field. If referencing both the location object and the Location field in the same snippet, you can differentiate between the two by using System.Location for the field and Schema.Location for the object.

enter image description here

The code to fix this error will be very similar

String location = Schema.describeSObjects(new List<String>{'Location'})[0].getName();
System.debug(location);
DescribeSObjectResult objectDescribe = ((SObject)Type.forName('Schema.'+location).newInstance()).getSObjectType().getDescribe();
0

Performance tests exhibit that in the current release Schema.describeSObjects method perform three times faster than the path ((SObject)Type.forName(devName).newInstance()).getSObjectType().getDescribe()

This means it is better to use just method Schema.describeSObjects which does fail without the Schema prefix in the name of the object.

So it is possible just to use this code to get dynamically schema describe

DescribeSObjectResult objectDescribe = Schema.describeSObjects(new List<String>{'Address'})[0];

or

DescribeSObjectResult objectDescribe = Schema.describeSObjects(new List<String>{'Location'})[0];
1
  • Really? I remember doing these tests several years ago and ((SObject)Type.forName(devName).newInstance()).getSObjectType().getDescribe() was giving better performance
    – Patlatus
    Commented Dec 24, 2020 at 17:05

You must log in to answer this question.

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