Summary
I am trying to simplify some code for a page that makes a callout, then logs the request and response. I stumbled across a scenario in which the log record appears to create successfully, but then no longer exists outside the transaction boundary.
Why does the insert
succeed but the record ceases to exist immediately outside the transaction?
MVR
Page
<apex:page controller="Demo">
<apex:pageMessages rendered="{!someProperty}" />
</apex:page>
Controller
public class Demo
{
public Boolean someProperty
{
get
{
HttpRequest request = new HttpRequest();
request.setEndpoint('https://someUri');
request.setMethod('GET');
new Http().send(request);
Integration_Log__c log = new Integration_Log__c();
insert log;
system.debug(log.Id);
return false;
}
}
}
Error
If I take the above log.Id
and navigate to the record, I get:
Data Not Available
The data you were trying to access could not be found. It may be due to another user deleting the data or a system error. If you know the data is not deleted but cannot access it, please look at our support page.
I can't see the record via query either.
Further Investigation
I changed the getter pattern to use an explicitly defined method and got a different error.
Controller
public Boolean getSomeProperty()
{
insert new Integration_Log__c();
return false;
}
Error
DML currently not allowed
An unexpected error has occurred. Your development organization has been notified.
And the debug log shows:
System.LimitException: DML currently not allowed
Additional Questions
Is DML not allowed in a Visualforce
getter? I can't find any official reference that is the case. In fact, the only reference I can find is an eight year old blog post by Wes Nolte. It's certainly allowed in getters in general. For example placing the above getter logic into Execute Anonymous
will cause the record to insert successfully.