不使用Salesforce标准clone()方法,如何实现Opportunity记录全字段克隆?
自定义Opportunity全字段克隆实现方案(禁用标准clone()方法)
现有代码的核心缺陷
- 硬编码查询字段范围,仅拉取
Name、CloseDate、StageName3个字段,其余标准字段、自定义字段完全无法读取 - 硬编码逐字段赋值逻辑,每新增一个需要克隆的字段,都要手动修改SOQL和赋值代码,维护成本极高,无法实现全字段覆盖
- 未利用Apex sObject的通用动态存取能力,灵活性为零
可行实现思路
完全基于Salesforce sObject的动态元数据存取能力实现,全程不依赖系统自带的clone()方法,核心逻辑是:
- 通过Schema Describe动态获取Opportunity对象所有可写入的字段,自动过滤系统只读、自动生成的无需克隆的字段
- 动态拼接SOQL语句拉取源记录的全量可克隆字段值
- 遍历所有可克隆字段,通过sObject的通用
get()/put()方法将源记录的值逐字段赋值到新的目标记录 - 执行插入操作完成克隆
优化后可直接运行的代码
public class Cloningwithout { // 可根据业务调整的排除克隆字段清单(系统自动生成、无需复制的字段) private static final Set<String> EXCLUDED_CLONE_FIELDS = new Set<String>{ 'Id', 'IsDeleted', 'CreatedDate', 'CreatedById', 'LastModifiedDate', 'LastModifiedById', 'SystemModstamp', 'LastActivityDate', 'LastViewedDate', 'LastReferencedDate' }; public static void insertclone(){ Opportunity opp = new Opportunity( Name='Opportunity2', CloseDate=date.parse('06/07/2012'), StageName='Prospecting' ); insert opp; Id oppRecordId = opp.Id; clone1(oppRecordId); } public static void clone1(Id sourceId){ // 1. 动态筛选所有可纳入克隆范围的字段 List<String> cloneableFields = new List<String>(); Map<String, Schema.SObjectField> oppFieldMap = Opportunity.sObjectType.getDescribe().fields.getMap(); for(String fieldApiName : oppFieldMap.keySet()){ Schema.DescribeFieldResult fieldDescribe = oppFieldMap.get(fieldApiName).getDescribe(); // 纳入规则:不在排除清单内、当前上下文有读取权限、字段支持创建操作 if(!EXCLUDED_CLONE_FIELDS.contains(fieldApiName) && fieldDescribe.isAccessible() && fieldDescribe.isCreateable()){ cloneableFields.add(fieldApiName); } } // 2. 动态构建SOQL查询源记录 String sourceQuery = 'SELECT ' + String.join(cloneableFields, ',') + ' FROM Opportunity WHERE Id = :sourceId LIMIT 1'; Opportunity sourceOpp = Database.query(sourceQuery); // 3. 逐字段手动赋值到新目标记录(全程未调用标准clone()方法) Opportunity targetOpp = new Opportunity(); for(String fieldApiName : cloneableFields){ Object fieldValue = sourceOpp.get(fieldApiName); targetOpp.put(fieldApiName, fieldValue); } // 4. 插入克隆后的新记录 insert targetOpp; } }
实现注意事项
- 排除清单可灵活调整:如果需要保留原记录的
OwnerId,就不要将其加入排除集合;如果需要给克隆记录设置新的负责人,可在赋值完成后单独覆盖OwnerId字段 - 权限适配:该方案运行时需要当前代码执行上下文对所有纳入克隆范围的字段拥有读取、创建权限,否则会抛出权限异常
- 子记录拓展:该方案仅克隆Opportunity主记录本身的字段,如果需要同步克隆Opportunity下的OpportunityLineItem、Contact等关联子记录,可在主记录克隆完成后,用同样的动态逻辑拉取子记录、逐字段赋值插入即可
- 特殊字段适配:自动编号、公式、汇总字段因为本身是只读属性,会被自动过滤排除,不会出现插入报错的问题
内容的提问来源于stack exchange,提问作者Sandesh Hase
相关产品推荐
相关产品推荐

