Apex Fundamentals & Collections
Data types, sObjects, List/Set/Map patterns, DML vs Database methods and exception handling.
Developer 2 min readApexCollectionsDMLExceptions
Apex is Salesforce's strongly typed, Java-like language. It runs on the platform, inside governor limits, and is saved/compiled in the org.
Primitive types
apex
Integer count = 5; Long big = 9000000000L;
Decimal price = 19.99; Double ratio = 0.75;
String name = 'Acme'; Boolean active = true;
Id accountId = '001000000000001AAA';
Date today = Date.today(); Datetime now = Datetime.now();
String comparison with == is case-insensitive; use .equals() for case-sensitive.
sObjects
apex
Account acc = new Account(Name = 'Acme', Industry = 'Technology');
acc.AnnualRevenue = 1000000;
insert acc; // acc.Id is now populated
// Generic sObject access
SObject so = acc;
so.put('Rating', 'Hot');
Object rating = so.get('Rating');
Collections — the three you must master
apex
// List: ordered, allows duplicates
List<String> stages = new List<String>{ 'Prospecting', 'Closed Won' };
stages.add('Negotiation/Review');
// Set: unique, unordered — great for Ids
Set<Id> accountIds = new Set<Id>();
for (Contact c : contacts) accountIds.add(c.AccountId);
// Map: key -> value, O(1) lookups
Map<Id, Account> accById = new Map<Id, Account>(
[SELECT Id, Name FROM Account WHERE Id IN :accountIds]
);
Account parent = accById.get(someContact.AccountId);
The "collect Ids → one query into a Map → loop and look up" pattern is the heart of bulkified code.
DML statements vs Database methods
apex
insert accs; // all-or-none: one bad record throws DmlException
Database.SaveResult[] results = Database.insert(accs, false); // partial success
for (Integer i = 0; i < results.size(); i++) {
if (!results[i].isSuccess()) {
for (Database.Error e : results[i].getErrors()) {
System.debug(accs[i].Name + ': ' + e.getStatusCode() + ' ' + e.getMessage());
}
}
}
| Statement | Database method | Extra |
|---|---|---|
insert | Database.insert(list, allOrNone) | SaveResult |
update | Database.update(list, allOrNone) | SaveResult |
upsert | Database.upsert(list, externalIdField, allOrNone) | UpsertResult (isCreated()) |
delete / undelete | Database.delete(...) / Database.undelete(...) | DeleteResult |
Exceptions
apex
try {
update opps;
} catch (DmlException e) {
System.debug(e.getNumDml() + ' failed: ' + e.getDmlMessage(0));
} catch (Exception e) {
System.debug(LoggingLevel.ERROR, e.getMessage());
throw e; // rethrow if you can't handle it
} finally {
System.debug('always runs');
}
// Custom exception: name must end with "Exception"
public class InsufficientCreditException extends Exception {}
throw new InsufficientCreditException('Credit limit exceeded');
System.LimitException(governor limits) cannot be caught.
Interview questions
- List vs Set vs Map — when do you use each?
- What's the difference between
insertandDatabase.insert(records, false)? → All-or-none vs partial success with per-record results. - How do you build a
Map<Id, SObject>from a query in one line? →new Map<Id, Account>([SELECT …]). - Can you catch a LimitException? → No.