0

I approached problem which obviously is not solvable by a trigger. I need to update Contacts's field on change on it's owner's field. Not accomplishable in trigger because MIXED_DML_EXCEPTION. Workaround it use future handle, however I have another future handler on Contact, so dead end this way. That's why I need to use workflow rule.

I created a rule which is triggered on object Contact with rule criteria set to Owner.Active = false. This does not fire at all. If I set rule criteria to any field on actual Contact, it does fire. If I set rule to any other field on Contact's owner, it does not fire. Do I get it wrong and it is not possible to set rule criteria to object's lookup? Or should that work?

2 Answers 2

0

As you've found out, you can access cross-object fields in workflow rules, but cross-object fields cannot trigger workflow.

Intuitively, this makes perfect sense. Workflow rules for Object X are triggered when there is a change on Object X. You're updating a field on User, not Contact. Therefore, workflow rules are not evaluated on Contact because you aren't changing a Contact, you're changing a User.

If you don't need the Contacts owned by a User to be updated immediately, then you might try creating a Schedulable class, and having it run on a schedule The documentation on the Apex Scheduler will help with that.

If you do need Contacts to be updated immediately, and you're absolutely certain that updating Contacts from a User trigger causes the mixed DML error, then you really don't have much choice besides going async.

You don't need to use an @future method. Implementing the Queueable interface (the documentation on Queueable Apex will be helpful there) is one way to work around that issue.

Another way to make it work would be to make your @future calls smarter. We can detect if we're in an async context or not. The key here is to not directly call your @future method. If you're already in an async context, just call a non-future version of your code. The general pattern for that looks like this...

public class MySmarterFuture{
    // A custom exception class isn't strictly required, but is good practice
    public class MySmarterFutureException extends Exception{}

    public static void run(List<Id> sobjIds){
        try{
            if(system.isFuture() || system.isBatch() || system.isScheduled()){
                system.debug('running async, calling normal run method');
                doNormal(sobjIds);
            } else {
                if (Limits.getFutureCalls() < Limits.getLimitFutureCalls()){
                    system.debug('running future run method');
                    doFuture(sobjIds);
                } else {
                    // Error out
                    throw new MySmarterFutureException('Hit the single transaction @future call limit');
                }
            }
        } catch(Exception e){
            system.debug('Caught Exception');
            // Good idea to do some explicit notification here, otherwise the
            //   issues encountered in async contexts are generally silent
        }
    }

    @future
    public static void doFuture(List<Id> sobjIds){
        // No need to duplicate your code, just call the doNormal method!
        // The fact that we're in this block of code at all means that we've
        //   already taken care of getting into an async context.
        doNormal(sobjIds);
    }

    private static doNormal(List<Id> sobjIds){
        // The work that you would normally put in your future method goes in this
        // non-future method instead
    }
}
0

You must try this

enter image description here

You must check whether the owner is changed and then add field updated.

Make sure to choose the highlighted radio selection because the formula only works on the selected radio selection in the image.

You must log in to answer this question.

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