An object Id in Apex that matches no objects

SOQL and SOSL both support the “in” operator in their “where” clauses. I was recently using this mechanism where a small number of Id values were being generated in some code and passed about as Set<Id>. But in one case I wanted the set to contain only an Id that would not match any of the objects. Where this is done directly in SOQL or SOQL, I have seen the string ‘0000000000000000’ (15 zeroes) used and so assumed that would be ok. But when such a String is cast to an Id you get an exception that contains the message “Invalid id”. It appears that the Apex code that handles Ids is a little fussier than the SOQL and SOSL engines.

The good news though is that there appears to be a simple solution to the problem as illustrated in the testOk method of the code below. The getKeyPrefix method “Returns the three-character prefix code for the object” and this combined with 12 zeros can be converted to an Id and appears to never match any objects. But it does cost an expensive and governor limited describe call per object type.

@isTest
private class IdTest {
    @isTest
    static void testOk() {
        ok(Account.SObjectType.getDescribe().getKeyPrefix() + '000000000000', Account.SObjectType);
        ok(Contact.SObjectType.getDescribe().getKeyPrefix() + '000000000000', Contact.SObjectType);
        ok(Task.SObjectType.getDescribe().getKeyPrefix() + '000000000000', Task.SObjectType);
    }
    @isTest
    static void testNotOk() {
        notOk('000000000000000', Account.SObjectType);
        notOk('123456789012345', Account.SObjectType);
        notOk(Account.SObjectType.getDescribe().getKeyPrefix() + '123456789012', Account.SObjectType);
        notOk(Account.SObjectType.getDescribe().getKeyPrefix() + '222222222222', Account.SObjectType);
    }
    private static void ok(String idString, SObjectType sobType) {
        Id id = (Id) idString;
        System.assertEquals(0, Database.countQuery('select Count() from ' + sobType + ' where Id = \'' + id + '\''));
    }
    private static void notOk(String idString, SObjectType sobType) {
        try {
            Id id = (Id) idString;
            System.assert(false, 'exception expected');
        } catch (Exception e) {
            System.debug('exception=' + e);
            System.assert(e.getMessage().contains('Invalid id'));
        }
        // While the above cast fails, the string value can be use in SOQL
        System.assertEquals(0, Database.countQuery('select Count() from ' + sobType + ' where Id = \'' + idString + '\''));
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s