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

时间:2012-01-02 21:56:06

标签: salesforce apex-code

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

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

有更好的方法吗?

4 个答案:

答案 0 :(得分:2)

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

可能有更好的方法来完成此任务。 future方法可以查询它需要作用的对象吗?也许你可以传递ID列表,未来的方法可以在WHERE子句中使用它。如果它是大量对象,批量顶点可能有助于避免调控器限制。

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

我的答案基本相同。我所做的是准备一个自定义队列对象,其中包含所有相关的ID(用户/联系人/潜在客户/等)以及我的自定义数据,然后从@Future调用处理。这有助于调控器限制,因为您只能从队列中提取您的标注和未来限制允许您在单个线程中处理的内容。例如,对于Facebook,您可以为每个标注批量更新20个配置文件更新。每个@Future允许10个标注,每个线程允许10个@Future调用,相当于2000个人的Facebook个人资料更新 - 如果您正确处理您的批次,并且您有足够的Salesforce席位允许此次@Future调用。最后我检查了每个用户每个用户200次@Future电话。

当您执行触发的标注时,道路变窄了,这就是我假设您正在尝试做的事情,因为您首先需要在@Future方法中调出。如果您没有触发,那么只要您在处理任何DML之前执行它们,您就可以处理您的标注。换句话说,推迟任何特定线程中的任何数据保存,直到你完成呼叫。

但是,因为听起来你需要从触发器中调出来,所以在sObjects中将它批量化是真正的方法。这有点工作,但基本上序列化现有的堆数据是这里的旅行之路。还要考虑从每小时安排的Batch Apex调用中执行此操作,因为使用队列方法,您最终可以处理所有标注。如果您在特定线程中遇到调控器限制(或者更确切地说,避免命中它们),它将在一小时后唤醒并完成队列中剩余的工作。启动该过程看起来像这样:

String jobId = System.schedule('YourScheduleName', '0 0 0-23 * * ?', new ScheduleableClass());

这将每小时实例一次ScheduleableClass实例,这将从队列对象中提取工作并处理最大量的标注。

祝你好运,并为沮丧感到抱歉。

答案 3 :(得分:1)

我想回答一下我是如何轻易地做到这一点的,以防万一其他人偶然发现这个问题。 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;
}

无论如何,似乎比使用新的自定义对象添加数据库杂乱更好,并且无需再次查询数据库以获取您已有的信息,这只会让我内心受伤。

几乎忘了添加链接:https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_json_json.htm