You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apex扩展类更新关联字段报错:INVALID_ID_FIELD求助

Fixing INVALID_ID_FIELD Error When Saving Associated Account Field in Visualforce Mass Edit

Let’s walk through what’s causing this error and how to fix it properly:

Why You’re Seeing the Error

Your current ContactExt class uses controller.getRecord(), which in a mass edit context (with recordSetVar) returns an empty Contact template (no ID)—not the actual selected contacts you’re editing. When you call update record; on this empty record, Salesforce throws the "record id cannot be empty" error because you can’t update a record without an ID.

Additionally, even if you fixed the ID issue, editing a.Account.Organization_Size__c directly in Visualforce won’t automatically update the Account record—you need to explicitly handle that in your Apex code, since the Contact StandardController only manages Contact records, not their related Accounts.

Step 1: Update the Apex Extension Class

Replace your ContactExt class with this version, which handles mass selected records and properly updates associated Accounts:

public class ContactExt { 
    private ApexPages.StandardSetController setController;
    private Map<Id, Account> accountsToUpdate = new Map<Id, Account>();

    public ContactExt(ApexPages.StandardSetController controller) { 
        setController = controller;
        // Load all selected records if none are pre-selected (for initial page load)
        if(setController.getSelected() == null || setController.getSelected().isEmpty()){
            setController.setPageSize(setController.getResultSize());
        }
    } 

    public PageReference save(){ 
        try{
            // Get all selected Contact records from the mass edit list
            List<Contact> selectedContacts = (List<Contact>)setController.getSelected();
            
            // Collect and deduplicate Accounts that need their Organization_Size__c updated
            for(Contact con : selectedContacts){
                if(con.AccountId != null && con.Account != null && con.Account.Organization_Size__c != null){
                    if(accountsToUpdate.containsKey(con.AccountId)){
                        // Use the latest value entered for the Account (handles multiple Contacts linked to same Account)
                        accountsToUpdate.get(con.AccountId).Organization_Size__c = con.Account.Organization_Size__c;
                    } else {
                        accountsToUpdate.put(con.AccountId, new Account(
                            Id = con.AccountId,
                            Organization_Size__c = con.Account.Organization_Size__c
                        ));
                    }
                }
            }

            // Update all selected Contacts first
            update selectedContacts;

            // Update the associated Accounts if there are any changes
            if(!accountsToUpdate.isEmpty()){
                update accountsToUpdate.values();
            }

            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'Contacts and their associated Accounts updated successfully!'));
            return null;
        } catch(DmlException e){
            ApexPages.addMessages(e);
            return null;
        }
    } 
}

Step 2: Clean Up the Visualforce Page

You have duplicate "Organisation Size" columns in your page table—remove the extra one to avoid confusion, and keep only the one bound to the Account field. Here’s the updated pageBlockTable section:

<apex:pageBlockTable value="{!selected}" var="a" id="table">
    <apex:column headerValue="Name">
        <apex:inputField value="{!a.Name}"/>
    </apex:column>
    <apex:column headerValue="Phone">
        <support:clickToDial number="{!a.Phone}" entityId="{!a.Id}"/>
    </apex:column>
    <apex:column headerValue="Mobile Phone">
        <apex:inputField value="{!a.MobilePhone}"/>
    </apex:column>
    <apex:column headerValue="Email">
        <apex:inputField value="{!a.Email}"/>
    </apex:column>
    <apex:column headerValue="Title">
        <apex:inputField value="{!a.Title}"/>
    </apex:column>
    <apex:column headerValue="Account">
        <apex:inputField value="{!a.AccountId}"/>
    </apex:column>
    <apex:column headerValue="Description">
        <apex:inputField value="{!a.Description}"/>
    </apex:column>
    <apex:column headerValue="Organisation Size (Account)">
        <apex:inputField value="{!a.Account.Organization_Size__c}"/>
    </apex:column>
</apex:pageBlockTable>

Key Fixes Explained

  • Mass Record Handling: We now use setController.getSelected() to get all the actual contacts you’re editing, not an empty template.
  • Account Update Logic: We collect all unique Accounts that need their Organization_Size__c updated, deduplicate them, and run a separate DML update for those Accounts.
  • Error Handling: Added a try-catch block to display meaningful error messages on the page instead of crashing silently.
  • Clean UI: Removed duplicate columns to avoid user confusion.

Important Notes

  • Make sure the user running this page has Edit permissions on the Account object and the Organization_Size__c field.
  • If multiple Contacts link to the same Account, the last entered Organization_Size__c value will be saved (this is standard mass edit behavior, but you can adjust the logic if needed).
  • Keep Salesforce’s DML limits in mind—this code handles up to 1000 records (the standard limit) in one save.

内容的提问来源于stack exchange,提问作者Werner Adewole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:04:37