Hot answers tagged

64

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.


53

in APIv26 there's a new method, Id.getSObjectType() which returns a sObject token you can use to find it's type. Sample code: String objectAPIName = someId.getSObjectType().getDescribe().getName(); This new style uses much less heap space and script statementsCPU time in addition to being much simpler and is highly recommended. Don't do this anymore, but ...


43

You can resolve this in your test class by using System.runAs. System.runAs ( new User(Id = UserInfo.getUserId()) ) { ...your setup-object DML... } If you need to do this in a non test scenario @future, Batch Apex, apex:actionFunction or something as simple as user button flow, it can be used to separate the transactions. The Salesforce documentation ...


37

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 (...


35

You've got the general idea from your answer. Dynamic Apex and Dynamic SOQL are the best way to reflect on SObject's and as you've discovered you can determine the type easily. I would ensure however your method takes a list of SObject so it can implement bulkfication. public void createTask(List<SObject> records) You can use the List method ...


28

There is no way to Select * with SOQL. You can however work-around this limitation by using dynamic SOQL and describe methods to get all of the fields on the object. This is described in detail in this post by Cory Cowgill: Building Dynamic SOQL - Select All Query


25

New feature coming in the next release: Foo__c f = Foo__c.sobjecttype.newSObject( recordTypeId, // can be null true); // loadDefaultValues


24

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, ...


22

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....


20

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)...


19

If you already know the ID of the SObject you want to update then you're right, there's no need to waste a query just to get an SObject instance to work with. Your sample code is very close to working, but you need to remember that the constructors for SObjects are special and accept named arguments, something unique to them in all of apex. Your sample code ...


18

Sadly I have to report the answer to your question is no. For me this is the final peace of Dynamic Apex to complete the ability to build truly 100% dynamic Apex libraries and solutions. I've searched for workarounds and can find none, the addError methods on SObject use a highly specialised way to reference the field which is to hard code the field ...


17

The question is not very clear, but you could do something with the JSON.deserializeUntyped method as following: testobject__c tObj = [SELECT boolfield__c,currencyfield__c,datetimefield__c,formulafield__c,Id,Name,numberfield__c,textfield__c,url_field__c FROM testobject__c limit 1]; Map<String, Object> m = (Map<String, Object>) JSON....


17

Once you have the sObjectType you should be able to construct the sObject instance using the sObjectType.newSObject(ID Id) method. You can get the sObjectType from the Id using the Id.getSObjectType() method; Map<Id, String> idsToUpdate = new Map<Id, String>(); // Put the Id's and associated name values in the map List<SObject> ...


17

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 ...


17

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 ...


17

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

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 ...


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

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 ...


13

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

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 ...


13

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....


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 ...


11

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

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 ...


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);


10

You can use apex describe to get the record type details of any object. This information will be correct for the running user. Schema.DescribeSObjectResult dsr = Account.SObjectType.getDescribe(); Schema.RecordTypeInfo defaultRecordType; for(Schema.RecordTypeInfo rti : dsr.getRecordTypeInfos()) { if(rti.isDefaultRecordTypeMapping()) { ...


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