Salesforce 什么';无法将堆对象传递给未来方法的解决方法是什么?

Salesforce 什么';无法将堆对象传递给未来方法的解决方法是什么?,salesforce,apex-code,Salesforce,Apex Code,这是我这边最大的刺之一。SFDC不允许将复杂对象或对象集合用作将来调用的参数。这方面最好的解决方法是什么 目前,我所做的是在多个基本体的并行数组中传递,这些基本体基于索引形成一个完整的对象。这意味着如果我需要传递一组用户,我可以传递3个字符串数组,比如-Name[]、Id[]和Role[]。名称[0],Id[0]。角色[0]是第一个用户,等等。这意味着我必须构建所有这些数组,并构建未来的方法,以便在另一端重构相关对象 有没有更好的方法可以做到这一点?至于为什么一旦Apex“事务”完成,VM就会被

这是我这边最大的刺之一。SFDC不允许将复杂对象或对象集合用作将来调用的参数。这方面最好的解决方法是什么

目前,我所做的是在多个基本体的并行数组中传递,这些基本体基于索引形成一个完整的对象。这意味着如果我需要传递一组用户,我可以传递3个字符串数组,比如-Name[]、Id[]和Role[]。名称[0],Id[0]。角色[0]是第一个用户,等等。这意味着我必须构建所有这些数组,并构建未来的方法,以便在另一端重构相关对象

有没有更好的方法可以做到这一点?

至于为什么一旦Apex“事务”完成,VM就会被销毁。一般来说,salesforce不会序列化您的对象图以便在将来恢复


也许有更好的方法来完成这项任务。未来的方法能否查询它需要处理的对象?也许您可以传递ID列表,未来的方法可以在WHERE子句中使用它。如果是大量对象,batch apex可能有助于避免调控器限制。

我建议创建一个新的自定义对象,专门用于存储自定义apex类中所需的信息。然后,您可以将它们插入数据库,然后在调用它们之前,在
@future
方法中查询记录


然后,一旦调用成功完成,您就可以从数据库中删除这些记录,以保持整洁。

我的答案基本相同。我要做的是准备一个带有所有相关ID(User/Contact/Lead/etc)的自定义队列对象,以及从@Future调用处理的自定义数据。这有助于管理器限制,因为您只能从队列中提取调用和未来限制允许您在单个线程中处理的内容。例如,对于Facebook,您可以在每个调用中批量更新20个配置文件。每个@Future允许10次呼叫,每个线程允许10次@Future呼叫,这相当于2000次个人Facebook个人资料更新-如果您正确处理批次,并且如果您有足够的Salesforce席位允许此数量的@Future呼叫。我上次检查时,每24小时每个用户有200@Future calls

当您执行触发调用时,道路会变得狭窄,我假设您首先是基于@Future方法调用的需要而尝试这样做的。如果您不在触发器中,那么只要在处理任何DML之前处理调用,您就可以处理调用。换句话说,推迟任何特定线程中的任何数据保存,直到调用完毕

但是,因为听起来你需要从触发器中调用,所以在sObjects中批处理它才是真正的方法。这是一点工作,但本质上序列化现有堆数据是这里的必经之路。也可以考虑从小时计划的批量APEX调用来完成这一操作,因为使用队列方法,您最终可以处理所有的标注。如果您在特定线程中遇到调控器限制(或者更确切地说,避免触及它们),它将在一小时后醒来,并完成队列中剩余的工作。启动该流程的过程如下所示:

String jobId = System.schedule('YourScheduleName', '0 0 0-23 * * ?', new ScheduleableClass());
这将每小时实例化一次ScheduleableClass实例,它将从队列对象中提取工作并处理最大数量的调用


祝你好运,也为我的挫折感到抱歉。

我只是想回答一下,如果其他人偶然发现这个问题,我是如何轻松地做到这一点的。Apex的函数可以轻松地将对象序列化和反序列化到JSON编码中。假设我有一个案例列表,我需要在未来的通话中处理这些案例:

String jsonCaseList = '';
List<Case> caseList = [SELECT id, Other fields FROM Case WHERE some conditions];
//Populate the list

//Serialize your list
jsonCaseList = JSON.serialize(caseList);

//Pass jsonCaseList as a string parameter to your future call

futureCaseActivity(jsonCaseList);

@future
public static void futureCaseActivity(string jsonCases){

  //De-serialize the string back into a list of cases
  List<Case> futureCaseList = (List<Case>)JSON.deserialize(jsonCases, List<Case>);

  //Do whatever you want with your cases
  for(Case c : futureCaseList){
    //Stuff
  }

Update futureCaseList;
}
字符串jsonCaseList='';
List caseList=[选择id,从某些条件下的Case中选择其他字段];
//填充列表
//序列化您的列表
jsonCaseList=JSON.serialize(案例列表);
//将jsonCaseList作为字符串参数传递给将来的调用
未来案例活动(jsonCaseList);
@未来
公共静态void futureCaseActivity(字符串jsonCases){
//将字符串反序列化回案例列表
List futureCaseList=(List)JSON.deserialize(jsonCases,List);
//你想用你的箱子做什么都行
对于(案例c:未来案例列表){
//东西
}
更新未来案例清单;
}
无论如何,这似乎是一个比使用新的自定义对象添加数据库混乱更好的选择,并且避免了需要再次查询数据库中已有的信息,这只会让我内心受伤


差点忘了添加链接:

这是一个咆哮还是一个问题?我承认两者都有点。如果有更好的方法,我将不胜感激。我想了解在这方面的最佳实践是什么,因为这是我经常遇到的问题。我想问题是,“不能将堆对象传递给未来方法的解决方法是什么?”好的,我已经编辑了这个问题和内容,以减少咆哮,并使用了你的问题标题Jeremy。如果使用sObjects,我可以看到这是如何工作的。我的问题可能因调用而变得复杂,调用通常需要复杂的数据,而这些数据不一定存储在sObject中(可能是某个自定义类对象)。但是,当涉及到sobject时,我会记住这一点。您能从future方法进行出站调用吗?这是future的一个常见用例。出站调用是从future方法发出的-这就是为什么我首先尝试在future方法中获取这些对象。另一件我必须克服的事情是管理者的限制,所以我必须小心如何构建未来和调用。这绝对是一种可能性,对于开发人员和系统来说,在系统中构建对象、在代码中创建对象、保存对象、查询对象、删除对象等方面似乎都有很多工作要做