Salesforce 認定 Platform デベロッパー 無料問題 7 / 10 ・ 分野3: ユーザインターフェース
次のクラスで、共有ルールを効かせてクエリしたい。利用者の操作で new OrderService.Finder().findAll() が呼ばれる。 public with sharing class OrderService { public class Finder { public List<Order> findAll() { return [SELECT Id FROM Order]; } } } 内部クラス Finder の共有の宣言について、Apex 開発者ガイドの説明に合うものはどれか。
- 内部クラスには共有の宣言を書けないので、共有ルールを効かせるには Finder のクエリに WITH USER_MODE を付ける
- 内部クラスは外側のクラスの with sharing を引き継ぐので、Finder に宣言を足さなくても共有ルールが効く
- Finder は OrderService の中の部品なので、Finder を外から呼ばず、OrderService に足したメソッドの中から呼ぶ形に書き換える
- 内部クラスは外側のクラスの共有の設定を引き継がないので、Finder にも with sharing を宣言する
正解と解説を見る
正解: D
正解の理由
「Using the with sharing, without sharing, and inherited sharing Keywords」の Implementation Details は、内部クラスも外側のクラスも with sharing で宣言できるが、内部クラスは外側のクラスの共有の設定を引き継がないと書いている。そのほかの場合は、共有の設定はクラスに含まれるすべてのコード(初期化コード・コンストラクタ・メソッド)に当たる。OrderService の with sharing は Finder には及ばないので、Finder で共有ルールを効かせるには、Finder にも with sharing を宣言する。
違う選択肢
「内部クラスは外側のクラスの with sharing を引き継ぐので、Finder に宣言を足さなくても共有ルールが効く」… ガイドの Implementation Details は、内部クラスは外側のクラスの共有の設定を引き継がないと書いている。OrderService の with sharing は Finder には及ばない。引き継ぐのは、あるクラスを継承(extends)したクラスが親クラスの設定を受け取る場合である。
「内部クラスには共有の宣言を書けないので、共有ルールを効かせるには Finder のクエリに WITH USER_MODE を付ける」… ガイドは、内部クラスも外側のクラスも with sharing で宣言できると書いている。Finder に with sharing を書けばよく、ユーザーモードに頼る必要は無い。共有の宣言を書けないのはトリガーである。
「Finder は OrderService の中の部品なので、Finder を外から呼ばず、OrderService に足したメソッドの中から呼ぶ形に書き換える」… ガイドは、内部クラスは外側のクラスの共有の設定を引き継がないと書いている。Finder を OrderService のメソッドの中から呼ぶように書き換えても、Finder のメソッドには OrderService の with sharing は及ばない。Finder 自身に with sharing を宣言する。
似た規則との違い
同じ節は、あるクラスを継承したクラスは親クラスの共有の設定を引き継ぐこと、トリガーには共有の宣言を書けないことも挙げている。ガイドは、宣言の無い Apex は既定では安全でないとして、クラスには常に共有の宣言を書くよう強く勧めている。