Hot answers tagged

90

You need getSobject() to traverse relationship "up" in a dynamic way. sObject acc = [SELECT Owner.Profile.Name FROM Account LIMIT 1]; String profileName = (String) acc.getSobject('Owner').getSobject('Profile').get('Name'); System.debug(profileName); Check all dynamic get* methods in the Sobject instance methods docs.


43

I know this approach is strange because you are still working with a List<SObject>, but when you assign it you can make it more specific (e.g. List<Account>) by using Type.forName and Type.newInstance methods. public static void dynamicUpsert(List<SObject> records) { Schema.SObjectType sObjectType = records.getSObjectType(); if (...


40

Update: Spring '21 Release (API v51+) adds new SOQL FIELDS function can select all fields of an object. Refer to documentation Knowing that new FIELDS function must have a LIMIT of at most 200, when used with ALL or CUSTOM keyword, the workaround below can still be useful. There is no way to Select * with SOQL. You can however work-around this limitation ...


27

Get All Parent objects. for(Schema.SobjectField strFld: Account.SobjectType.getDescribe().fields.getMap().Values()) { if(strFld.getDescribe().getType() == Schema.DisplayType.REFERENCE) { system.debug('==parent object='+strFld.getDescribe().getReferenceTo()); } } Get All Child objects. Schema.DescribeSObjectResult R = Account....


25

An alternate way to do this without going through Schema.getGlobalDescribe(): String myString = 'Account'; SObjectType sObjType = ((SObject) Type.forName(myString).newInstance()) .getSObjectType(); speed comparison between above and getXXDescribe methods


25

I use SObject as a key when I want to use a composite key. For example, say I want to find duplicates based on first name, last name, and email. I might loop through a list of contacts, and create a contact that matches the keys I'm using: Incoming.put(new Contact(FirstName= record.FirstName, LastName= record.LastName, Email= record.Email), record); Then, ...


24

Here is the way: // I have Account name in String String objectStr = 'Account'; // Convert to schema.sObjectType Schema.SObjectType convertType = Schema.getGlobalDescribe().get(objectStr); // Create an instance of that type Sobject genericObject = convertType.newSObject(); // or if I know it is Account !! why making Sobject ? Account acc = (Account)...


23

I'm not sure you could do exactly that, but what you could do is use the Id instance class to achieve what you need, for example: Schema.SObjectType sobjectType = myId.getSObjectType(); String sobjectName = sobjectType.getDescribe().getName(); SObject record = Database.query('Select Id, Name From ' + sobjectName + ' Where Id = :myId'); See ID class ...


20

Yes, deepClone will only pull in fields you have in memory. In this case, you do indeed have to query for them. You should question why you need every field, but if you want to maintain a configurable option, I recommend you use a Field Set. This will allow you some flexibility in which fields to copy, without forcing you to copy every single field. public ...


19

I created some helper classes for this. You can find them here. There are 3 classes: xt, xs and xr. They contain also some other tools I couldn't separate for this answer, but the method you need is xs.query() in xs.cls. To get all straight into your Org, just use the "Deploy to Salesforce" link. The usage is very simple. Just go somewhere to Execute ...


19

I suggest that rather than relying on some utility class, you become familiar with the platform's APIs so you can compose the appropriate solution each time you want to query all the fields, particularly if your queries are simple and only involve one object. Whoever gets to maintain the code in the future will thank you for keeping things simple and direct ...


18

The sObject has a native function getPopulatedFieldsAsMap that converts from an sObject to a Map<String,Object>. This was released in Summer '16 which is probably why the other answers resort to using JSON serialization to accomplish this. Account a = new Account(); a.name = 'TestMapAccount1'; insert a; a = [select Id,Name from Account where id=:a.Id]...


18

As a regular user, the only way would be to either attempt to create a record from a related object then look at the URL to get the prefix or view an existing record and look at the url. If the user has access to the dev console you can debug this line of code: system.debug(logginglevel.error,OBJECTAPINAME.sobjecttype.getDescribe().getKeyPrefix()); ...


16

UPDATED: Following comment request see below for related fields There is no method on the SObject class that can be used to determine if a field has been queried. I would add this to the 'hasError' method request as well btw! In the meantime I can see two options... Catching SObjectExceptions You can catch the exception that is generated from ...


16

Mechanics You need to use the get and put methods. Each method supports both String and SObjectField as the parameter type: // terse myObject.put('UniqueId__c', myObject.get('ExternalId__c')); // verbose SObjectField fieldToGet = MyObject__c.ExternalId__c; SObjectField fieldToPut = MyObject__c.UniqueId__c; Object value = myObject.get(fieldToGet); myObject....


15

You could vote for this Provide an additional addError method on SObject that accepts a field name idea, but as it has got nowhere in the last 5 years there is no reason to expect any progress in the next 5 years.


15

Using complex objects as Map keys can have unexpected consequences. In your example, the insert causes the Id of the key Account to be updated so the hashCode and equals methods of the Account produce different results after that. But the Map was setup with the original hashCode and equals results. Effectively you have modified the key and that has broken ...


14

Update We can now query those 01I object ids and 00N field ids directly without Tooling API or callouts. List<EntityParticle> entities = [ SELECT DurableId FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'MyCustom__c' ]; This will return: DurableId 01I7F000001fbTC.LastViewedDate 01I7F000001fbTC.LastReferencedDate ...


13

You can get this data on the lookup field using the DescribeFieldResult.getReferenceTo() method. From that field describe result you can retrieve the related object's name or the display label. // describe of your lookup field Schema.DescribeFieldResult f = Schema.sObjectType.Account.fields.Employer_Root__c; System.debug('Relationship Name: ' + f....


13

The comparison operators don't work the way you think they do, not even across all objects. Let's focus on SObject and SObject[] types for this question, since that's your question. == acts as a deep comparison, comparing every field in an SObject with the same field in the other SObject. This basically means that it's a byte-wise operation, and the results ...


13

An SObject represents a specific table in the database that you can discretely query. The API Name is what you reference as ending in __c. Standard SObjects have names like Account or Opportunity, whereas Custom SObjects and Custom Settings have names like MyObject__c or MySetting__c. Custom Settings are special objects you can get without a query. You can ...


13

I know that when you serialize an SObject it has some extra information on it that you might not expect: Contact c = new Contact(); system.debug(json.serialize(c)); Result: {"attributes":{"type":"Contact"}} I think the error message is simply telling you that you need to include this in your JSON that you send back to the controller so that it knows what ...


12

Without sample code, it's hard to be certain, but I think you are saying you have something like this: //You have a custom object, Widget__c, with a lookup to account Widget__c widget = [select id, name, Account__c from Widget where id = :someId]; List<Account> accounts = new List<Account>(); accounts.add(widget.account__c); // <-- error ...


11

This works fine for me. Ran a couple tests and all of the below work. VF Page <apex:page controller="GenericTest"> {!test['name']} {!test1.obj['name']} <apex:repeat value="{!testList}" var="test2"> {!test2.obj['name']} </apex:repeat> <apex:pageBlock> <apex:pageBlockTable value="{!testList}" ...


11

You don't need to have a return type to get data back to the callee, and sometimes this is more convenient. Here's my version of a "get values from records" implementation: public static void getValuesFromRecords(Object[] result, SObject[] source, SObjectField field) { for(SObject record: source) { result.add(record.get(field)); } } Typical ...


11

Sfdcfox explains a great reason to use this, but at a more abstract level the reason it's supported it because maps can have any type as a key. In a model where custom classes, or any other type, can be used as keys there seems little reason to make a special case for forbidding SObjects. Using an apex class as a map key has equally odd behavior (without ...


11

I suggest building and serializing nested maps for this: Map<String, Object> m = new Map<String, Object>(); for (options__C opt:options) { m.put(opt.Name__c, new Map<String, Boolean>{ 'isActive' => opt.isActive__c, 'isRequired' => opt.isRequired__c }); } return JSON.serialize(m);


11

You need to use the name pointing reference: MyObject__c record = new MyObject__c(); record.Parent__r = new Parent__c(Name='Populated'); The above is functionally equivalent to putSObject: MyObject__c record = new MyObject__c(); record.putSObject('Parent__r', new Parent__c(Name='Populated')); You can also use name=value pairs in the constructor for CPU ...


11

Instantiate a new generic list and it won't carry over any type information. Simply casting to List<SObject> doesn't remove the fact it was originally a List<Account>. List<SObject> records = new List<SObject>(); records.addAll(accounts); records.addAll(opportunities);


10

You could use inner wrapper class as an abstraction of your vehicle object, create and populate list of those custom objects, and finally make the binding in the VF page to use the list of custom objects: Controller: public with sharing class YourController { public List<Vehicle> vehicles { get; set; } public YourController(ApexPages....


Only top voted, non community-wiki answers of a minimum length are eligible