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());
        }
    }
}
StatementDatabase methodExtra
insertDatabase.insert(list, allOrNone)SaveResult
updateDatabase.update(list, allOrNone)SaveResult
upsertDatabase.upsert(list, externalIdField, allOrNone)UpsertResult (isCreated())
delete / undeleteDatabase.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

  1. List vs Set vs Map — when do you use each?
  2. What's the difference between insert and Database.insert(records, false)? → All-or-none vs partial success with per-record results.
  3. How do you build a Map<Id, SObject> from a query in one line? → new Map<Id, Account>([SELECT …]).
  4. Can you catch a LimitException? → No.

Practice this