[salesforce] レコードIDでのDescribeとId.valueOf()の仕様変更
管理パッケージの開発を行う際は名前空間への対応が面倒に色々と考慮が必要ですが、対応策のひとつにレコードIDのみでDescribeを行い、対象レコードのオブジェクト情報を動的に取得しつつ動的クエリを実行する手法があります。
例えば以下のような単純化したソースで記します。
[html]
ID objRecId = Id.valueOf(‘0061000000NIw2X’);
Schema.SObjectType sObjType = objRecId.getSObjectType();
Schema.DescribeSObjectResult sObjResult = sObjType.getDescribe();
String objName = sObjResult.getName();
Map<String, Schema.SObjectField> sObjFieldMap = sObjResult.fields.getMap();
String queryField = ”;
for(Schema.SObjectField field:sObjFieldMap.values()){
//項目のapi参照名を取得する
Schema.DescribeFieldResult fResult = field.getDescribe();
if(queryField == ”){
queryField = fResult.getName();
}else{
queryField += ‘,’;
queryField += fResult.getName();
}
}
String query = ”;
query = ‘SELECT ‘;
query += queryField;
query += ‘ ‘;
query += ‘FROM ‘;
query += objName;
query += ‘ ‘;
query += ‘LIMIT 1’;
System.debug(query);
SObject sObj = Database.query(query);
System.debug(sObj.get(‘Id’));
System.debug(sObj.get(‘Name’));
for(String key :sObjFieldMap.keySet()){
System.debug(‘_/_/_/_/_/key:’+key);
System.debug(‘_/_/_/_/_/value:’+sObj.get(key));
}
[/html]
上記のようなコードであればオブジェクト名を固定値で持つ必要がないので名前空間を持つ管理パッケージでの開発では重宝されます。
ただし、Summer’13からId.valueOf()の引数仕様がバリデーションが厳密になり、引数には15桁若しくは18桁のSalesforce ID形式の文字列でなければならなくなりました。
Summer’13以前までは任意の文字列や空文字列でも、そのまま返していましたので落ちる事なく処理は続行されていました。
従ってソースの書き方によっては古いソースで以下の点が鬼門になり、これまで動作していたソースが急に動作しなくなる事態も起きているようです。
- VisualforcePageからのパラメータ取得しているケース
- VisualforcePageからRemoteActionで取得したJSON文字列をDeserializeしているケース
- Id.valueOf()直後の値をsystem.debugしているケース
つまりは上記サンプルも最低でもId.valueOf()の引数にSalesfroce ID例外処理をきちんと行う必要があるということになります(要はこれまでもきちんとコーディングしていれば困らないということですね^^;)