1

I have an Apex Class:

    public with sharing class Lookup
    {
    public static void findOpportunities(List<Custom_Object__c> records)
    {
        Set<Id> OppsIds = new Set<Id>();
        for (Custom_Object__c record : records) OppsIds.add(record.custom_field__c);

        Map<String, Opportunity> Opps = new Map<String, Opportunity>();
        for (Opportunity Opp : [
            SELECT Id, custom_field_2__c FROM Opportunity
            WHERE custom_field_2__c IN : OppsIds
        ]) Opps.put(Opp.Name, Opp);

        for (Custom_Object__c record : records)
            if (Opps.containsKey(record.custom_field__c))
                record.Opportunity__c = Opps.get(record.custom_field__c).Id;
    }
}

And a trigger:

trigger UpdateOpportunityLookup on Custom_Object__c (after insert, after update) 
{

    if (trigger.isAfter)
    {
        if (trigger.isInsert)
        {
            Lookup.findOpportunities(trigger.new);
        }
    }
}

The OLIs are being sent from another system on this custom object, as related records. There is lookup field from the related records to the Opportunity object that I am trying to populate.

The Class is meant to query if the custom_field__c on the custom_object__c has the same value as custom_field_2__c and populate the lookup with the correct Opportunity.

I have managed to save it successfully, but I am getting an error message:

Apex script unhandled trigger exception by user/organization / caused by: System.StringException: Invalid id: 895

External entry point Trigger.UpdateOpportunityLookup: line 8, column 1

and it stops the OLIs from being sent to SF.

Both fields are Text Data Type and contain numeric numbers.

The custom_field_2__c on the Opportunity I am querying to have the same value as custom_field__c is External ID = ticked.

1 Answer 1

5

This variable cannot be a Set<Id>:

    Set<Id> OppsIds = new Set<Id>();

because the values you're receiving are not Salesforce Ids; they're arbitrary strings. Change the collection type to Set<String>.

The exception you're seeing is thrown when you attempt to create an Id value from something that is not an Id.

Additionally, this logic is incorrect:

    for (Opportunity Opp : [
        SELECT Id, custom_field_2__c FROM Opportunity
        WHERE custom_field_2__c IN : OppsIds
    ]) Opps.put(Opp.Name, Opp);

Your Map should be keyed on custom_field_2__c, not Name.

6
  • Thanks a lot, @david. I've made the changes you suggested and I stopped receiving the error message. The only issue I am having is with the trigger. It stops the related records from being created in SF. I have been testing it and if it's active it stops them. If I am making it inactive, it is creating the records. I want the trigger to fire after the records have been created in Salesforce. I am not sure what I am missing...
    – SSimion
    Jan 3, 2020 at 15:59
  • Presumably it's throwing an exception. Triggers don't stop record creation unless they cause, or add, some error to stop the transaction.
    – David Reed
    Jan 3, 2020 at 16:02
  • Unfortunately, I don't get an error message. Should I try to re-throw the exception, to troubleshoot the issue?
    – SSimion
    Jan 3, 2020 at 16:21
  • You should be able to either receive an error message (or see one in the debug logs, or the return values to your remote system) or obtain records.
    – David Reed
    Jan 3, 2020 at 20:22
  • I've generated a few debug logs and I got an email with the error: "UpdateOpportunityLookup: execution of AfterInsert caused by: System.FinalException: Record is read-only" and I have been looking into the error, and I can't update fields on triggered records in an after trigger. As my trigger doesn't rely on the id's. I will modify the trigger to before and test again.
    – SSimion
    Jan 6, 2020 at 16:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .