Quando scrivi del codice e fai dei test su Salesforce, ti sarà capitato di ricevere l'errore "Too Many DML Statements: 1". Di solito l'errore avviene con: Lightning Components, Lightning Web Components, and Visualforce Page.
Visualforce Page
<apex:page controller="InsertAccount" readOnly="true">
<h1>Ciao {!$User.FirstName}</h1>
<p>Inserisci i dati del Candidato</p>
<apex:form>
Name: <apex:inputField value="{!acc.Name}"/>
<apex:commandButton action="{!save}" value="Save"/>
</apex:form>
</apex:page>
Apex Class
public class InsertAccount{
public Account acc {get; set;}
public InsertAccount() {
acc = new Account();
}
public void save(){
insert acc;
}
}
Testando il codice scritto sopra, riceviamo il seguente errore nella Visualforce Page:
Visualforce Error System.LimitException: Too many DML statements: 1
Error is in expression '{!save}' in component <apex:commandButton> in page test: Class.InsertAccount.save: line 7, column 1
Il problema è causato dall'attributo readOnly della apex:page settato a "true". Infatti, semplicemente modificando readOnly="false" l'errore non viene più mostrato.
Sebbene le Visualforce Page che utilizzano la modalità read-only per l'intera pagina non possono utilizzare operazioni di Data Manipulation Language (DML), possono però chiamare i metodi getter, setter, e action che influiscono sulla forma e su altri elementi dell'interfaccia utente nella pagina.
Lightning Components / Web Components
public class updateAccount{
@AuraEnabled(cacheable=true)
public static void updateAccounts(){
List<Account> lstAcc = new List<Account>();
for(Account acc:[SELECT Id, Name FROM Account Limit 1]){
acc.Name = 'LWC_Test';
lstAcc.add(acc);
}
if(!lstAcc.isEmpty()){
update lstAcc;
}
}
}
In quest'altro caso, o simili, per risolvere l'errore basta semplicemente eliminare il parametro (cacheable=true) accanto alla notazione @AuraEnabled.
La linea guida generale è memorizzare nella cache (contrassegnare come memorizzabili) qualsiasi azione idempotente e non-mutante.
Un'azione idempotente è un'azione che produce lo stesso risultato anche se chiamata diverse volte. Per esempio:
- getPage(1) è idempotente e dovrebbe essere memorizzata nella cache
- getNextPage() non è idempotente e non dovrebbe essere memorizzata nella cache
Un'azione non-mutante è un'azione che non modifica i dati. Mai memorizzare nella cache un'azione che può eseguire un'operazione come: creare, update, or delete. Per esempio:
- updateAccount(sObject) è un'azione mutante e non idempotente e quindi non dovrebbe essere memorizzata nella cache.