Be Good & Do Good!

Apex – Update “non-setup” objects from a “setup” object like User

Dilemma

As this page of the Apex docs indicates, you can’t just make a User trigger that updates a Contact or an Account, because it’s forbidden to modify those “non-setup” objects from a “setup” object like User.

Solution

Fortunately there is a simple solution: the @future annotation.  The @future annotation allows you to create Apex that runs asynchronously at some point in the future (in my tests I’ve found that it runs immediately, or at least very soon after the trigger executes).  Methods that use @future are subject to different limits than normal trigger operations because @future methods don’t hold up the trigger (and therefore the entire user experience) while they’re working.  Therefore @future methods are often used to perform long-running web service callouts from triggers asynchronously.  However, they can also be handy for a case like ours, where we want to update an object that we’re not normally eligible to update.

Calling a method that has been marked as @future is just like calling any other static method.  Here’s my trigger, short and sweet:

trigger UpdateContactFromPortalUser on User (after update) {
	//We only want to run on the single item that the user edited
	if (Trigger.new.size()==1) {
		User u =  Trigger.new[0];
		//And only if it's a portal user
		if (u.ContactId!=null) {
		UpdateContactFromPortalUser.updateContacts(u.Id);
		}
	}
}

Let’s see how that works.  In the example given here, I just update a couple of fields from the user record: the name, the email address, and the title.

global class UpdateContactFromPortalUser {
    @future
    public static void updateContacts(String userId) {
    	User u = [select ContactId,Email,FirstName,LastName,Title
    				from User
    				where Id=:userId];

    	if (u!=null && u.ContactId!=null) {
	    	Contact c = new Contact(Id=u.ContactId);

			c.Email = u.Email;
			c.FirstName=u.FirstName;
			c.LastName=u.LastName;
			c.Title=u.Title;
			update c;
		}

Source :  http://blogs.salesforce.com/support/2009/01/index.html

1 Comment

  1. Salesforce Blog

    Action chaining is a technique to handle the infamous “MIXED_DML_OPERATION, DML operation on setup object is not permitted Error” problem.

    You may not know it but there are two types of objects that you can interact with on the platform. One is “setup” object and the other is a “non-setup” object. A “setup” object is one that must be edited from the setup or builder area of the platform. These object include the User object, Ogranization object, Email templates and so on.

    See this article for details DML operations of a non-setup sObject and a setup sObject

    Read the full article and check out the source code at Visualforce Action Chaining http://wiki.developerforce.com/index.php/Visualforce_Action_Chaining

Leave a Reply

Your email address will not be published. Required fields are marked *