The Silver Lining

A developer's view of Cloud Computing platforms & technologies.

DML currently not allowed

with 14 comments

This almost belongs in my sarcastically titled, “Meaningful Error Messages ..” series, but as it has traceable causes, I thought I’d write something up on it’s most frequent causes (I meant to write this up a few months ago, but it slipped my mind (find it in your heart to forgive an ol’ developer) and now I think it’s time the world knew).

‘DML currently not allowed’, what could that mean? Well it means that DML isn’t allowed. And that it’s not allowed right now, but with the slight promise that given time, it will be allowed. Often in the past, hoping against hope, I kept on pressing that button/link/onclick-area, but the cloud never changed it’s mind. With a sigh I constructed the google-search query and began trundling through the results.

Strangely enough I’ve found myself in similar situations a few times, but with a different source and solution each time. So now let’s try, you and I, to write-up a nice, consolidated list of the whys-and-hows of ‘DML currently not allowed’.

Situations that may cause ‘DML currently not allowed’

  1. Venturing a DML operation within a component controller.
  2. Set in motion a DML operation within a class constructor.
  3. Undertaking a DML operation within a getter or setter.

A short time in the past, I wanted to write my own debugger within Apex, something similar to log4j (I have big love for that logger).

Alas alack,

it could not be,

mainly because,

of points 2 and 3.

- Wes

Don’t judge me because I wax lyrical.  So about those situations..

Fixing previously mentioned situations

  1. This one is surprisingly easy to fix. There is a VisualForce component attribute that can be set such that DML is allowed within it’s controller i.e.<apex:component allowDml=”true” ../>
  2. This one is a bit trickier. Often you need some sort of DML to occur on a page-load, so you try to schtuck it into the controller constructor.. but that ain’t gonna work. I would suggest in most cases that you use the ‘action’ attribute on the tag i.e. <apex:page action=”{!doStuff}” .. />. This method will run after the constructor and work in the same way as all other action methods.
  3. In my opinion, this is the trickiest one of all, and it’s a doozy… especially for developers who’ve worked in other OOP languages. The problem here is that only action methods can be used to perform DML. What about DML with getters and setters? No can do. With VisualForce driven by Apex your mindset has to shift, and you need to think of methods as belonging to two broad categories, action methods, and data methods. You should only be performing DML in action methods (those guys that do stuff and return PageReferences or Void), and use data methods to pass object and variable values around.

In the dark recesses of my mind there’s a whisper of a memory of similar errors happening if you get your trigger -> callout -> DML operation in the wrong order. But I’m (mostly) certain that this results in a ‘You have uncommitted work pending. Please commit or rollback before calling out’ error, so that resolution doesn’t belong here.

That’s all I have on this topic, maybe you have another point I’ve missed. If so, I’d be rather happy if you shared it.

About these ads

Written by Wes

November 23, 2009 at 6:14 pm

14 Responses

Subscribe to comments with RSS.

  1. Love the verse…

    DMLs might not be allowed at all on a specific object.

    Steve

    Steve

    November 23, 2009 at 6:20 pm

  2. Thanks this helped a lot! :-) all i needed was the allowDML=”true” :-P

    You ROCK!

    Randi

    December 2, 2009 at 12:05 am

    • You’re making me blush here! Glad I could be of service ma’am.

      Wes

      December 2, 2009 at 10:19 am

  3. You cant NOT update a user record and a data record in the same transaction, you will get a mixed dml statement, because a user record is treated as metadata

    fede l

    December 4, 2009 at 7:26 pm

  4. Wes,

    I’ve been struggling this one for a while and appreciate someone else’s frustration with it. But you left out the “best” part (unless I missed the mention) – You cannot trap this exception at runtime. Which makes writing your code to take an alternate path challenging. We have created an ExceptionHandling.cls that logs unexpected errors to a custom object in order to notify a developer and for proactive defect tracking and resolution purposes. So we get this “DML currently not allowed” error at runtime because of the exception logging.

    I logged a case with Premier Tech Support on this issue hoping that it might become trappable in the future or to provide a list of areas that this exception may occur so we can avoid them.

    Thanks,
    Mike

    Mike

    February 11, 2010 at 11:55 pm

  5. “Well it means that DML isn’t allowed. And that it’s not allowed right now, but with the slight promise that given time, it will be allowed. Often in the past, hoping against hope, I kept on pressing that button/link/onclick-area, but the cloud never changed it’s mind”

    This was me last night :)

    d3developer

    March 19, 2010 at 4:36 pm

  6. This worked for me. Thanks!

    rdehler

    November 4, 2011 at 5:49 pm

  7. Having exhausted my reportoire of rude words on situations 2 and 3 in my code, I thank you from the bottom of the swear box for this article.

    I would like to add, as this is the first helpful article in the google results (hello future readers, read xkcd) that some page load actions happen twice, especially where PDF rendering a page is concerned, so you will need to check if you’ve done your action before.

    NickM

    November 21, 2011 at 5:27 pm

  8. thx for solution 2 – the action attribute solved it for me.

    Chuck Norris

    February 22, 2012 at 2:10 pm

  9. A great and very useful article. Thanks for posting!

    Chris Merrill

    March 8, 2012 at 8:17 pm

  10. [...] Use at your own risk!!– there are reasons for why it is that way in the 1st place( http://th3silverlining.com/2009/11/23/dml-currently-not-allowed/ ) Share this:TwitterFacebookLike this:LikeBe the first to like this [...]

  11. Very useful post.

    Sreekanth

    May 3, 2013 at 6:11 am

  12. Good job! I love your writing style

    Mathieu Beausoleil

    October 28, 2013 at 7:19 pm


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

Follow

Get every new post delivered to your Inbox.

Join 1,850 other followers

%d bloggers like this: