DML is not allowed in a constructor. Is there a known reason behind this limit?

I have been searching for the answer & haven't found anything which addresses the question. May be it's not documented anywhere(Or google doesn't know where it is).

3 Answers 3


The act of creation of object shouldn't have immediate dangerous side effects. If I'll create hundreds of your objects - will they all fire 1 DML?

This also holds true in Visualforce / any web context. The mere act of displaying some page (might be VF embedded in detail page layout, might be requested by some nasty Javascript like CSRF) shouldn't cause say deletes to run. You can work around it with stuff like <apex:page ... action="{!afterCtorHook}"> but it would be caught for example in Salesforce security review.

User should understand what he's doing ("are you sure you want to delete these 100 records?"), click something to confirm that this is really what he wants to do...

Check these too:

  1. http://wiki.developerforce.com/page/Secure_Coding_Cross_Site_Request_Forgery (actually have a look at all items from http://wiki.developerforce.com/page/Secure_Coding_Guideline, well worth a read).
  2. https://developer.salesforce.com/forums?id=906F0000000957bIAA
  3. Try submitting your app to security scan? The report should provide some examples & explanations of the vulnerabilities: http://wiki.developerforce.com/page/Security_Tools
  • 1
    – eyescream
    Commented Feb 26, 2014 at 17:06
  • 2
    Nail on the head... it's not allowed because it poses a huge security risk.
    – Matt Lacey
    Commented Feb 26, 2014 at 22:38
  • Isn't the most likely reason that there is an underlying platform implementation limitation leaking out into the Apex code we write? That seems more likely to me than a feature being deliberately programmed in to protect users and then not documented. (I'm only commenting out of frustration at having to refactor some code out of a constructor that inserts a custom setting to get the default values set when the setting hasn't been managed.)
    – Keith C
    Commented May 7, 2014 at 17:42
  • @KeithC Don't think so, it's perfectly fine to have DML in constructors that aren't called in VF-related constructors: public class Hello { public Hello(){ insert new Account(Name = 'works'); } }. You'd have to ask somebody from SF to be sure :) But the concept of simply navigating to url (HTTP GET request) for all safe operations and confirming you know what you're doing (HTTP POST/PUT/PATCH/DELETE...) if you want to change the server's state is quite old: w3.org/2001/tag/doc/whenToUseGet.html TL;DR: I believe it was a conscious design decision.
    – eyescream
    Commented May 7, 2014 at 18:00
  • 1
    There is also now a trailhead for this that I really recommend: trailhead.salesforce.com/en/trails/security_developer Commented Oct 2, 2017 at 18:09

Using insert/update/delete in constructor is a bad practice in any language.

Establishing connection to DB - OK.
Constructor is used to create an object and initialize it's parameters; nothing more. I was trying to search for a better explanation but I failed.

I was taught to avoid using insert/update/delete operations when I worked with Java. It was enterprise project. The company had a lot of documents regarding how to code. And they have this rule to not use constructor for insert/update/delete. I think Select was ok. But I doubt it.

First, using DML in constructor will slow down initialization of your object. Second, it may fail and object just doesn't create at all. Second problem has it's roots from C/C++ where memory should be allocated for an object. In this case memory is allocated but object isn't created there.


A quick solution would be to place the dml operations in a single method that you call from the page action parameter.

for example VF page

<apex:page controller="pageController" action="{!doSomeDMLStuff}">

APEX Class

public pageController{

  private boolean doDML;

  public pageController(){

   //run some logic to decide if you need to execute dml statements

   if(logic = true){

      doDML= true;

  //the method called from the page action

  public pagereference doSomeDMLStuff(){

         //run DML statements 

     return null;

  • That's pretty much what @eyescream said... Commented Sep 8, 2014 at 13:43
  • What if you use component instead of visualforce page?
    – Brane
    Commented Jul 29, 2016 at 10:28
  • @user3850805 - <apex:component controller="XYZ" allowDML="true"> ...
    – Tim Lewis
    Commented Sep 9, 2017 at 2:21

You must log in to answer this question.

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