Security.stripInaccessible()移除所需字段致Upsert失败求助
问题根源
主明细(Master-Detail)字段的特性是仅在插入记录时允许赋值,更新操作时字段不可写。Security.stripInaccessible(AccessType.UPSERTABLE, ...)会同时校验插入和更新的权限逻辑:当执行Upsert时,对于已有记录(更新场景),该字段因不可写会被过滤;对于新记录(插入场景),Upsertable的统一校验逻辑也会把这个字段移除,导致你预先赋值的Quote__c丢失。
解决方案
拆分Upsert为独立的Insert和Update操作,针对不同场景用对应的权限校验类型:
先把待处理记录拆成「新增记录」和「已有记录」两个列表:
- 新增记录:
Id为null的记录,需要保留Quote__c字段关联主记录 - 已有记录:
Id不为null的记录,主明细字段不可修改,无需保留该字段
- 新增记录:
分别对两个列表执行权限过滤和DML操作:
List<OrderFee__c> insertList = new List<OrderFee__c>(); List<OrderFee__c> updateList = new List<OrderFee__c>(); // 拆分记录列表 for(OrderFee__c fee : actualOrderFee) { if(fee.Id == null) { // 新增记录:确保Quote__c已赋值 if(fee.Quote__c == null) { fee.Quote__c = recordId; } insertList.add(fee); } else { updateList.add(fee); } } // 处理新增记录:用CREATABLE权限校验,保留Quote__c if(!insertList.isEmpty()) { List<SObject> filteredInsert = Security.stripInaccessible(AccessType.CREATABLE, insertList).getRecords(); insert filteredInsert; } // 处理更新记录:用UPDATABLE权限校验,无需Quote__c if(!updateList.isEmpty()) { List<SObject> filteredUpdate = Security.stripInaccessible(AccessType.UPDATABLE, updateList).getRecords(); update filteredUpdate; }
补充说明
- 主明细字段的更新限制是Salesforce原生规则,哪怕你有字段全权限,更新时也无法修改该字段,所以更新场景下不需要携带
Quote__c - 拆分操作后,既符合权限校验规则,又能保证新增记录的主明细关联正常建立
内容的提问来源于stack exchange,提问作者César Pulpón Pozuelo
相关产品推荐
相关产品推荐

