[SalesForce] DML When Component is Loaded

Preface:

I understand that DML is not allowed in getters/setters or constructors. The normal workaround to performing DML on page load is to use the action attribute on the page; however, that's not an option in this case.

Page:

<apex:page controller="testPageController">
    <c:testComponent/>
</apex:page>

Component:

<apex:component controller="testComponentController">
    <apex:form rendered="true">
        <apex:actionFunction action="{!init}" name="init"/>
    </apex:form>
    <script>
    init();
    </script>
</apex:component>

I have also tried a variant using $(document).ready(init()); as well as setTimeout to no avail.

When I move the <script> tag into the <apex:form> body, the error goes away; however, that's because the init method never fires.

Component controller

public class testComponentController {
    public void init() {
        update [SELECT Id FROM Contact LIMIT 1];
    }
}

I've also tried making the method return a null PageReference to no avail.

Error

When the page loads up I get the following:

DML currently not allowed

Knowing that I can't use getters, setters or constructors and apparently this doesn't work either, is there anyway to fire code when the component is loaded in a context that allows DML? Assume I don't have access to the VF page.

Update

I commented out the call to init and tried to call it from the developer console in chrome and still got the error.

Best Answer

As per the Visualforce Component Reference for <apex:component> there exists a Boolean attribute allowDML which enables executing DML within the component and the description for the same is as follows.

If this attribute is set to "true", you can include DML within the component. The default is "false". Allowing DML can cause side-effects that could be problematic for consumers using the component with partial page updates.

When allowing DML within a component, you should include rerender attributes so the consumer can appropriately refresh their page. In addition, you should detail, in the description of the component, what data is manipulated by the DML so that consumers of the component are aware of potential side-effects.

This should fix your issue.

Related Topic