+ Start a Discussion
Spencer EdieSpencer Edie 

LWC LimitException: Too many DML statements: 1

Hello all,
I'm getting the error in subject when I try to run this code:
@auraEnabled(cacheable=true)
public static void Equalize(string campaignsStr){
    string[] campaigns = (string[])JSON.deserialize(campaignsStr, list<String>.class);

    //Will hold the opportunities to update
    list<opportunity> updates = new list<opportunity>();

    //Will keep track of user ids and opp counts
    map<string, integer> owners = new map<string, integer>();	//String = OwnerID	Integer = opp count

    list<opportunity> opps = [SELECT Id, OwnerId FROM Opportunity WHERE Primary_Campaign_Filter__c IN :campaigns LIMIT 9999];
    System.debug('opps size: ' + opps.size());

    //Initializing the values of the owners map
    for(opportunity o: opps){
        if(owners.containsKey(o.ownerID)){
            owners.put(o.ownerID, owners.get(o.ownerID) + 1);
        }
        else{
            owners.put(o.ownerID, 1);
            System.debug('Adding owner ' + o.ownerId);
        }
    }

    //For each opportunity, if that owner already has more than the average,
    //give it to the person with the lowest opportunity count.
    integer threshold = opps.size()/owners.size() + 2;
    for(opportunity o: opps){
        if(owners.get(o.OwnerID) > threshold){
            string lowest = GetLowest(owners);
            owners.put(o.OwnerID, owners.get(o.OwnerID) - 1);
            owners.put(lowest, owners.get(lowest) + 1);
            o.OwnerID = lowest;
            updates.add(o);
        }
    }

    //PULL MY DEVIL TRIGGER
    System.debug('updates size: ' + updates.size());
    try{update updates;}
    catch(exception e){
        System.debug('exception: ' + e);
    }
}
I have seen solutions for Lightning Components (like https://developer.salesforce.com/forums/?id=906F0000000917DIAQ), but none that apply to Lightning Web Components. This is part of a component that has multiple other apex methods being called, and they all update fine.

Can anyone help me identify where the problem is?

Thanks!
 
Best Answer chosen by Spencer Edie
Spencer EdieSpencer Edie
SOLVED: Remove (Cacheable=true). Don't know why that fixed it, but here it is for anyone else who runs into this.

All Answers

Spencer EdieSpencer Edie
Notes from some debugging: running the same code as activated by a button in another sub-component produces the same error, but running the code in an anonymous window does not produce an error.
Spencer EdieSpencer Edie
SOLVED: Remove (Cacheable=true). Don't know why that fixed it, but here it is for anyone else who runs into this.
This was selected as the best answer
William Woodson 3William Woodson 3
My guess is that removing the Cacheable=true fixes it because the menthod returns void so there is nothing to cache.

 
Scott McClungScott McClung
It's because the equalize() method has a DML operation in it.

From the documentation: https://developer.salesforce.com/docs/component-library/documentation/lwc/apex
To improve runtime performance, annotate the Apex method with @AuraEnabled(cacheable=true), which caches the method results on the client. To set cacheable=true, a method must only get data, it can’t mutate (change) data.
To call an Apex method imperatively, you can choose to set cacheable=true. This setting caches the result on the client, and prevents Data Manipulation Language (DML) operations.
Karthickeyan B 2Karthickeyan B 2
If I remove cacheable=true then I am getting this Error. Let me know If someone can able to solve this.
.User-added image
Karthickeyan B 2Karthickeyan B 2
If you are using LWC for DML operation, Then Don't use the Wire. call Directly as I showed in the following Example. Here Next3 is the method that performs The DML operation. And Make sure that method Should Not contain  (Cacheable=true)
import { LightningElement,track,wire,api } from 'lwc';
import Next3 from '@salesforce/apex/RecordArchivePageCtrl.Next3';


export default class RecordArchivePage extends LightningElement {

    handleNext2(){
        this.progress = '4';
        this.firstPage = false;
        this.secondPage = false;
        this.thiredPage = false;
        this.fourthPage = true;
        Next3({selectedObject: this.selectedValue,sobjList:this.selectedRowUpdateList,recordMap:this.recordList}).then(result => {
            this.message = result;
            this.error = undefined;
            if(this.message !== undefined || this.message !== '' || result!==undefined || result !== '' ) {
                // eslint-disable-next-line no-alert
                alert("Workig "+result);
                
            }
        })
        .catch(error => {
            this.message = undefined;
            this.error = error;
            // eslint-disable-next-line no-console
            console.log("error s", JSON.stringify(this.error));
        });
        
    }
}

Wire method. call the directly the method
brahmaji tammanabrahmaji tammana
This (http://auraenabled.com/2020/04/can-we-perform-dml-using-wire-service/)blog post probably discussed in detail on this error.

http://auraenabled.com/2020/04/can-we-perform-dml-using-wire-service/

In short, we cannot perform dml from lwc when the apex method decorated with auraenabled(cacheable=true), but if this method call in other ways, it works normally.