Какой обходной путь для неспособности передать объекты кучи будущему методу? - PullRequest
2 голосов
/ 03 января 2012

Серьезно, это один из самых больших шипов на моей стороне.SFDC не позволяет использовать сложные объекты или коллекции объектов в качестве параметров для будущего вызова.Каков наилучший обходной путь для этого?

В настоящее время то, что я сделал, передается в нескольких параллельных массивах примитивов, которые формируют полный объект на основе индекса.То есть, если мне нужно передать наборы пользователей, я могу передать 3 строковых массива, скажем - Name [], Id [] и Role [].Имя [0], идентификатор [0].и Role [0] - первый пользователь и т. д. Это означает, что мне нужно собрать все эти массивы и создать метод будущего для реконструкции соответствующих объектов на другом конце.

Есть ли лучший способсделать это?

Ответы [ 4 ]

2 голосов
/ 03 января 2012

Я бы предложил создать новый пользовательский объект специально для хранения информации, необходимой в вашем пользовательском классе Apex.Затем вы можете вставить их в базу данных и затем запросить записи в методе @future, прежде чем использовать их для выноски.

Затем, после успешного завершения выноски, вы можете удалить эти записи из базы данных.чтобы все было хорошо и аккуратно.

2 голосов
/ 03 января 2012

Мой ответ по сути тот же. То, что я делаю, это готовит пользовательский объект очереди со всеми соответствующими идентификаторами (Пользователь / Контакт / Ведущий / и т. Д.) Вместе с моими пользовательскими данными, которые затем обрабатываются из вызова @Future. Это помогает с ограничениями регулятора, поскольку вы можете извлекать из очереди только то, что ваши вызовы и будущие ограничения позволят вам обработать в одном потоке. Например, для Facebook вы можете получить до 20 обновлений профиля за одну выноску. Каждый @Future допускает 10 вызовов, а каждый поток разрешает 10 вызовов @Future, что равняется 2000 отдельным обновлениям профиля Facebook - ЕСЛИ вы правильно обрабатываете свои партии и ЕСЛИ у вас достаточно мест в Salesforce, чтобы разрешить такое количество вызовов @Future. Это 200 @ будущих звонков на пользователя в сутки, когда я последний раз проверял.

Дорога становится узкой, когда вы выполняете инициируемые выноски, что, как я полагаю, вы пытаетесь сделать, исходя из вашей потребности вызывать вызов в методе @Future в первую очередь. Если вы не находитесь в триггере, то вы сможете обрабатывать свои выноски до тех пор, пока вы делаете их перед обработкой любого DML. Другими словами, откладывайте сохранение данных в каком-либо конкретном потоке до тех пор, пока вы не закончите вызывать.

Но так как это звучит так, как будто вам нужно вызывать из триггера, пакетирование его в sObjects - действительно верный путь. Это немного трудоемко, но, по сути, сериализация существующих данных кучи - это путь, по которому нужно путешествовать. Также подумайте о том, чтобы сделать это с помощью ежечасного запланированного вызова Batch Apex, так как с подходом очереди вы сможете в конечном итоге обработать все ваши выноски. Если вы столкнетесь с ограничениями регулятора (или, скорее, избежите их попадания) в определенном потоке, он проснется через час и завершит работу, оставленную в вашей очереди. Запуск этого процесса выглядит примерно так:

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

Это будет создавать экземпляр ScheduleableClass один раз в час, который будет извлекать работу из объекта очереди и обрабатывать максимальное количество обратных вызовов.

Удачи и прости за разочарование.

2 голосов
/ 03 января 2012

Почему после завершения «транзакции» Apex виртуальная машина уничтожается. И вообще говоря, salesforce не будет сериализовать ваш граф объектов для возобновления в будущем.

Возможно, есть лучший способ выполнить эту задачу. Может ли будущий метод запросить объекты, на которые он должен воздействовать? Возможно, вы можете передать список идентификаторов, и будущий метод может использовать это в предложении WHERE. Если это большое количество объектов, пакетная вершина может быть полезна, чтобы избежать ограничений регулятора.

1 голос
/ 05 апреля 2016

Просто хотел дать мой ответ о том, как я это делаю очень легко на случай, если кто-нибудь еще наткнется на этот вопрос.В 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

...