function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sieb4mesieb4me 

System.LimitException: DML currently not allowed

Hi,

I am trying this code from the VF page, testing with hardcoded value, however it gives this error?

Does anyone know why.

What do i change to make it insert record?

 

Thanks

 

 

Visualforce Error
 

 

Class.escalationcd.getcaseemailmessage: line 41, column 1

 

 

public class escalationcd {
private final Case casenow;

public escalationcd(ApexPages.StandardController controller) {
this.casenow = (Case)controller.getRecord();
//String cid = casenow.id;

}

Public void getcaseemailmessage(){
List<Case> mescal = new List<Case>([Select Id,attach_casenumber__c from Case where Id = '500d0000003CkW4']);

map<Id,Id> oldnewCaseIdmap =new map<Id,Id>();
Map<Id, EmailMessage> emailMessageMap = new Map<Id, EmailMessage>{};
Attachment[] insertAttList = new list <Attachment>();
Attachment[] attList = new list <Attachment>();
list<Case> caseemlist=new list<Case>();

for(Case cs:mescal) {
if(cs.attach_casenumber__c!=null) {
oldnewCaseIdmap.put(cs.id,cs.attach_casenumber__c);
}
}

if(oldnewCaseIdmap.size()!=0) {
//get list of emails from old/current case
caseemlist=[Select (Select ParentId,fromaddress,fromname,subject,textbody,htmlbody,toaddress,ccaddress,status,messagedate From EmailMessages) 
From Case where Id in:oldnewCaseIdmap.keySet()];
}

for(Case c:caseemlist) {
for(EmailMessage em:c.EmailMessages) {
Emailmessage message = new Emailmessage (fromname = em.fromname,subject = em.subject,textbody = em.textbody,htmlbody = em.htmlbody,toaddress = em.toaddress,
fromaddress = em.fromaddress,ccaddress = em.ccaddress,status = em.status,messagedate = em.messagedate,ParentId=oldnewCaseIdmap.get(c.id));
//emlisttoinsert.add(message);
emailMessageMap.put(em.Id, message); 
}
}

if(emailMessageMap.values().size()>0) {
insert emailMessageMap.values();

attList = [select Id, Name, Body, ParentId from Attachment where ParentId in :emailMessageMap.keySet()];

for (Attachment a : attList) {
EmailMessage em = emailMessageMap.get(a.ParentId);
Attachment att = new Attachment(Name = a.Name, Body = a.Body, ParentId = em.Id);
insertAttList.add(att);
}
}

if(insertAttList.size() > 0) {
insert insertAttList;

}

}

 

Bhawani SharmaBhawani Sharma
Share your VF page code.
sieb4mesieb4me
<apex:page standardController="Case" extensions="escalationcd">

<apex:form >
<apex:pageBlock >
<apex:pageBlockSection >
<apex:inputField value="{!case.casenumber}"/>
<apex:inputField value="{!case.attach_casenumber__c}"/>

{!caseemailmessage}

<apex:commandButton action="{!save}" value="Save!"/>

</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Bhawani SharmaBhawani Sharma
Are you getting exception on page load?
sieb4mesieb4me
yes, that is true.
sandeep@Salesforcesandeep@Salesforce

This error come in following cases: 

1. in case of applyig in DML in constructor

2. in case of not using attribute in visualforce components "allowDML" to true.

 

but in you case both the case are not valid. please try once to remove DML from getter and chek it again i am woriking over this to get rid of this.

sieb4mesieb4me
thanks. removing, doesnt give error but the functionality doesnt work since records are not inserted.
sandeep@Salesforcesandeep@Salesforce

for inserting thoese record you need to use this logic of in serting records in a method and call this method as follows 

lets say yout method Name if  "insertingMethod()"

then code should be like 

<apex: controller="UtilClass" action="insertingMethod"  extension="extenedcode"/>

sieb4mesieb4me
it gives error
Error: caseat: Invalid qname for tag 'apex:'
Error: Invalid qname for tag 'apex:'.
code used in page
<apex: controller="escalationcd" action="{!casedmle}" extension="extenedcode"/>
also tried as you suggested
<apex: controller="escalationcd" action="casedmle" extension="extenedcode"/>

but same error.

in class i used method for dml

public class escalationcd {
private final Case casenow;
public escalationcd(ApexPages.StandardController controller) {
this.casenow = (Case)controller.getRecord();
//String cid = casenow.id;

}
Public void getcaseemailmessage(){
List<Case> mescal = new List<Case>([Select Id,attach_casenumber__c from Case where Id = '500d0000003CkW4']);

map<Id,Id> oldnewCaseIdmap =new map<Id,Id>();
Map<Id, EmailMessage> emailMessageMap = new Map<Id, EmailMessage>{};


list<Case> caseemlist=new list<Case>();
for(Case cs:mescal) {
if(cs.attach_casenumber__c!=null) {
oldnewCaseIdmap.put(cs.id,cs.attach_casenumber__c);
}
}

if(oldnewCaseIdmap.size()!=0) {
//get list of emails from old/current case
caseemlist=[Select (Select ParentId,fromaddress,fromname,subject,textbody,htmlbody,toaddress,ccaddress,status,messagedate From EmailMessages)
From Case where Id in:oldnewCaseIdmap.keySet()];
}
for(Case c:caseemlist) {
for(EmailMessage em:c.EmailMessages) {
Emailmessage message = new Emailmessage (fromname = em.fromname,subject = em.subject,textbody = em.textbody,htmlbody = em.htmlbody,toaddress = em.toaddress,
fromaddress = em.fromaddress,ccaddress = em.ccaddress,status = em.status,messagedate = em.messagedate,ParentId=oldnewCaseIdmap.get(c.id));
//emlisttoinsert.add(message);
emailMessageMap.put(em.Id, message);
}
}


} public void getcasedmle(Map<Id, EmailMessage> emailMessageMap)
{
Attachment[] attList = new list <Attachment>();
Attachment[] insertAttList = new list <Attachment>();
if(emailMessageMap.values().size()>0) {
insert emailMessageMap.values();

attList = [select Id, Name, Body, ParentId from Attachment where ParentId in :emailMessageMap.keySet()];

for (Attachment a : attList) {
EmailMessage em = emailMessageMap.get(a.ParentId);
Attachment att = new Attachment(Name = a.Name, Body = a.Body, ParentId = em.Id);
insertAttList.add(att);
}
}

if(insertAttList.size() > 0) {
insert insertAttList;
}
}


}

sieb4mesieb4me
OK I Was finally able to execute the code as below which doesnt give any error.
However i just now need help in ensuring that first value is saved on the page that opens up for new casenumber which is lookup field called attach_casenumber__c which is what user selects on the apex page that pops up and when use hits saves, the class should execute.

Currently, since initailly if the field attach_casenumber__c is not blank on the apex page, it still executes class code and attaches
emails and attachments.

How do i ensure in apex page that first save action on the button is done and only then the class code should execute.

thanks


Class:
public class escalationcd {
//private final Case casenow;
private final ApexPages.StandardController c;

public escalationcd(ApexPages.StandardController c) {this.c = c;}

Public PageReference getcaseemailmessage(){
List<Case> mescal = new List<Case>([Select Id,attach_casenumber__c from Case where Id = :c.getId()]);

map<Id,Id> oldnewCaseIdmap =new map<Id,Id>();
Map<Id, EmailMessage> emailMessageMap = new Map<Id, EmailMessage>{};

//Case casenow = (case)c.getRecord();
//string attv = casenow.attach_casenumber__c;

list<Case> caseemlist=new list<Case>();
for(Case cs:mescal) {
if(cs.attach_casenumber__c!=null ) {
oldnewCaseIdmap.put(cs.id,cs.attach_casenumber__c);
}
}

if(oldnewCaseIdmap.size()!=0) {
//get list of emails from old/current case
caseemlist=[Select (Select ParentId,fromaddress,fromname,subject,textbody,htmlbody,toaddress,ccaddress,status,messagedate From EmailMessages)
From Case where Id in:oldnewCaseIdmap.keySet()];
}
for(Case c:caseemlist) {
for(EmailMessage em:c.EmailMessages) {
Emailmessage message = new Emailmessage (fromname = em.fromname,subject = em.subject,textbody = em.textbody,htmlbody = em.htmlbody,toaddress = em.toaddress,
fromaddress = em.fromaddress,ccaddress = em.ccaddress,status = em.status,messagedate = em.messagedate,ParentId=oldnewCaseIdmap.get(c.id));
//emlisttoinsert.add(message);
emailMessageMap.put(em.Id, message);
}
}




Attachment[] attList = new list <Attachment>();
Attachment[] insertAttList = new list <Attachment>();
if(emailMessageMap.values().size()>0) {
insert emailMessageMap.values();

attList = [select Id, Name, Body, ParentId from Attachment where ParentId in :emailMessageMap.keySet()];

for (Attachment a : attList) {
EmailMessage em = emailMessageMap.get(a.ParentId);
Attachment att = new Attachment(Name = a.Name, Body = a.Body, ParentId = em.Id);
insertAttList.add(att);
}
}

if(insertAttList.size() > 0) {
insert insertAttList;
}
return null;
}

}

Page:

<apex:page standardController="Case" extensions="escalationcd">

<apex:form >
<apex:pageBlock >
<apex:pageBlockSection >
<apex:inputField value="{!case.casenumber}"/>
<apex:inputField value="{!case.attach_casenumber__c}"/>

<apex:commandButton action="{!save}" value="Save!"/>
<apex:page standardController="Case" action="{!getcaseemailmessage}" extensions="escalationcd">
</apex:page>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Bhawani SharmaBhawani Sharma
Use this on top

<apex:page standardController="Case" action="{!getcaseemailmessage}" extensions="escalationcd">

Don't use any inner page tag.
sieb4mesieb4me
thanks. i tried it but problem is here
as soon as user hits attach button on case pagelayout
a popup apex page opens and immediately code in the class getcaseemailmessage is executed which copies emails and attachment to the casenumber(attachcase field in class which is shown in popup apex page).
I want class to only execute once user hits save button on the apex page which opens up on hitting attach button.

Another thing is i want to put condition in class saying only copy attachment if (oldattachcase value) is different then the newone entered by user. In ordinary trigger code we could use oldmap or triger.old, how do i use that in apexpage/controller?
Bhawani SharmaBhawani Sharma
If this is the case, then you can remove action attribute from your page. Rename your getcaseemailmessage method to save method. Use commandbutton to call this save method.
<apex:commandbutton action="{!save}" value="Save" />
sivainkecsivainkec

public class myControllerExtension {
private final Account acct;


// The extension constructor initializes the private member
// variable acct by using the getRecord method from the standard
// controller.
public myControllerExtension(ApexPages.StandardController stdController) {
this.acct = (Account)stdController.getRecord();
}
public pagereference getGreeting() {
Contact ct= new Contact();
ct.lastname='Shiva';
ct.accountid=acct.id;
insert ct;
return null;

}
}

 

 

any one help me on this error.

 

i am getting System.LimitException: DML currently not allowed 

 

Class.myControllerExtension.getGreeting: line 15, column 1

MubeenMubeen

HI Sandeep,

 

The method you advised is working fine for me and i am able to attach a file successfully, Thanks a lot for the code.

 

Thanks,

Mubeen


sandeep@Salesforce wrote:

for inserting thoese record you need to use this logic of in serting records in a method and call this method as follows 

lets say yout method Name if  "insertingMethod()"

then code should be like 

<apex: controller="UtilClass" action="insertingMethod"  extension="extenedcode"/>