2012-01-02 172 views
2

これは真剣に私の側の最大の棘の一つです。 SFDCでは、複雑なオブジェクトやオブジェクトのコレクションを将来の呼び出しのパラメータとして使用することはできません。これに最善の回避策は何ですか?ヒープオブジェクトを将来のメソッドに渡すことができないための回避策は何ですか?

は、現在、私がやったことは、インデックスに基づいて完全なオブジェクトを形成するプリミティブの複数の並列配列で渡されます。意味私は、ユーザーのコレクションを渡す必要がある場合、私は3つの文字列配列を渡すことができます - 名前[]、ID []、および役割[]。名前[0]、Id [0]。と役割[0]は最初のユーザーなどです。つまり、これらの配列をすべてビルドし、相手方の関連オブジェクトを再構築するための将来のメソッドを構築する必要があります。

これを行うより良い方法はありますか? Apexの「トランザクション」を完了すると、VMが破壊される理由の

+0

これは暴言ですか、質問ですか? – Oded

+0

私はそれが少しだと認めます。これを行うより良い方法があれば、私はそれを感謝するでしょう。私はこの点でベストプラクティスが何であるかを学びたいと思っています。それは私が時々実行するものです。 –

+0

私は、将来のメソッドにヒープオブジェクトを渡すことができないための回避策は何ですか? –

答えて

2

。一般的に言えば、Salesforceは、将来の時点で再開するためにオブジェクトグラフをシリアル化しません。

このタスクを実行するより良い方法があるかもしれません。将来のメソッドは、それが動作する必要があるオブジェクトをクエリできますか?おそらくあなたはList of Idsを渡すことができ、将来のメソッドはこれをWHERE節で使用できます。オブジェクトが多数ある場合、バッチ頂点はガバナの制限を避けるために役立つ場合があります。

+0

sObjectsを使用している場合、それがどのように機能するのか分かりました。私の問題は、たぶんsObjectに格納されていない複雑なデータを必要とする、コールアウトを行うことでおそらく複雑になります(これはカスタムクラスオブジェクトかもしれません)。私はsObjectsがかかわっているときにこれを覚えておきます。 –

+0

今後の方法から発信コールを発信できますか?これは、先物の一般的な使用例です。 –

+0

アウトバウンドコールは将来のメソッドから行われています。そのため、私はこれらのオブジェクトを将来のメソッドで最初に取得しようとしています。私が戦わなければならないもう一つのことは、ガバナの制限です。したがって、先物とコールアウトの仕組みを慎重にする必要があります。 –

2

私は、カスタム頂点クラスに必要な情報を格納するために特別に新しいカスタムオブジェクトを作成することをお勧め。その後、これらをデータベースに挿入し、コールアウトに使用する前に@futureメソッドのレコードを照会することができます。コールアウトが正常に完了した後

次に、あなたがしていいときちんと物事を保つために、データベースからそれらのレコードを削除することができます。

+0

これは間違いなく、開発者とシステムにとって、システムにオブジェクトを構築し、コードで作成し、保存し、クエリを実行し、削除するなど、多くの作業のように思えます。おそらくそれについて行くために、少なくとも "ハック"方法。 –

2

私の答えは本質的に同じです。私が行うことは、すべての関連するID(User/Contact/Lead/etc。)と@Future呼び出しから処理されるカスタムデータを持つカスタムキューオブジェクトを準備することです。これはガバナーの制限に役立ちます。なぜなら、コールアウトと今後の制限により、単一のスレッドで処理できることをキューから引き出すことができるからです。たとえば、Facebookの場合、1回のコールアウトで20件のプロファイル更新を一括して処理できます。各@Futureは10個のコールアウトを許可し、各スレッドは@Futureコールを10個許可します。これは2000個のFacebookプロファイルのアップデートに相当します - バッチを適切に処理している場合、最後に私がチェックしたのは24時間あたり200人の@Future呼び出しです。あなたは私はあなたが最初の場所で@future方法にコールアウトするあなたの必要性に基づいてやろうとしていると仮定するものであるトリガーコールアウトを、実行しているとき

道路が狭くなります。引き金になっていない場合は、DMLを処理する前にコールアウトを処理できる限り、コールアウトを処理できます。つまり、呼び出しが完了するまで、特定のスレッドにデータを保存するのを延期します。あなたはのsObjectsでそれをバッチ処理、トリガーからコールする必要があるように聞こえるので、

は、しかし、実際に移動するための方法です。これはちょっとした作業ですが、既存のヒープデータを本質的にシリアライズすることは、ここを旅する道です。また、キューアプローチでは最終的にすべてのコールアウトを処理できるため、時間ごとにスケジュールされたバッチApexコールからこれを行うことを検討してください。特定のスレッドでガバナの制限に遭遇した場合(またはそれらを叩くのを避ける場合)、1時間後に起動し、キューに残っている作業を終了します。

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

これはあなたのキューオブジェクトから作業を引くとコールアウトの最大量を処理し1時間に1回ScheduleableClassのインスタンスをインスタンス化します。そのプロセスを起動するとこのようになります。

幸運にも、フラストレーションのために申し訳ありません。

+0

特に、「ソーシャルエンタープライズ」の新たな推進やサードパーティ製APIの使用増加に伴い、先物やコールアウトのようなものに対する制限を変更するかどうかは興味深いでしょう。あなたが言及した制限は、私が以前に遭遇したことでもあり、私はこの場合に先物を使用している理由です(ただちに10個以上のコールアウトを行うことができるようにするためです)。しかし、時間をかけて更新することは、常に実行可能な選択肢ではありません。 –

0

他の誰かがこの質問に遭遇した場合に備えて、私がこれをどのようにして行うのか、私の答えを伝えたいだけでした。 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

関連する問題