ユーザーを作成するSalesforceテストのMixed_dml_operationエラーを回避する方法
-
24-09-2019 - |
質問
Salesforceテストでは、SpeciIFCタイプのユーザーとしてテストの一部を実行するためにユーザーオブジェクトを作成する必要がある場合があります。
ただし、Salesforce Summer 08更新以来、同じテストでユーザーオブジェクトと通常のオブジェクト(アカウントなど)の両方を作成しようとすると、次のエラーが発生します。
Mixed_dml_operation、セットアップオブジェクトのDML操作は、セットアップ以外のオブジェクト(またはその逆)を更新した後に許可されません:ユーザー、元のオブジェクト:アカウント
Eclipse/Force.com IDEからテストを実行したときにエラーは発生しませんが、Salesforceに展開してからSalesforce内からテストを実行すると発生することに注意してください。
このエラーを回避するためにテストを書き直すにはどうすればよいですか?
エラーを引き起こすテストの簡単な例を次に示します。
static testMethod void test_mixed_dmlbug() {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
User u = new User(alias = 'standt', email='standarduser@testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser@testorg.com');
Account a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
System.runAs(u) {
a.PersonEmail = 'test@madeupaddress.com';
update a;
}
}
解決
ここにはまだ多くのSalesforceの人々はいません。
解決策を見つけましたが、なぜそれが機能するのかわかりませんが、機能します。
通常のオブジェクトにアクセスするテストのすべての部分は、このような現在のユーザーを明示的に使用するsystem.runasにラップする必要があります。
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
したがって、質問に記載されているtext_mixed_dmlbugメソッドの例は、次のようになります。
static testMethod void test_mixed_dmlbug() {
User u;
Account a;
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
Profile p = [select id from profile where name='(some profile)'];
UserRole r = [Select id from userrole where name='(some role)'];
u = new User(alias = 'standt', email='standarduser@testorg.com',
emailencodingkey='UTF-8', lastname='Testing',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='standarduser@testorg.com');
a = new Account(Firstname='Terry', Lastname='Testperson');
insert a;
}
System.runAs(u) {
a.PersonEmail = 'test@madeupaddress.com';
update a;
}
}
その後、Mixed_dml_operationエラーが発生しなくなります。
他のヒント
回避策を見つけたようです。このエラーが発生した場所で、なぜあなたがなぜあなたを追い払ったのかを試してみたかっただけです。
あなたはこの問題に遭遇していると思います(あたり http://www.salesforce.com/us/developer/docs/apexcode/content/apex_dml_non_mix_sobjects.htm):
DML操作では一緒に使用できないSobjects
一部のSobjectは、トランザクションごとに1つのタイプでDML操作を実行する必要があります。たとえば、アカウントを挿入してから、ユーザーまたはグループメンバーを1回のトランザクションに挿入することはできません。次のSobjectsは、トランザクションで一緒に使用することはできません。
* Group1 * GroupMember * QueueSObject * User2 * UserRole * UserTerritory * Territory
重要なのは、これの主な例外は、テストでRunasメソッドを使用している場合です。
加えて 夏08リリースノート (そのリンクはPDFです)言う:
以前のリリースでは、トリガーを含む単一のトランザクションでは、複数のタイプのSobjectでDML操作を実行できます。たとえば、アカウントを挿入してからユーザーを挿入できます。 08年夏の時点で、以下のSobjectsのリストから単一の種類のSobjectでDML操作のみを実行できます。
たとえば、アカウントを挿入してから、ユーザーを挿入するか、グループを更新してから、グループメンバーを挿入することはできません。
- グループ
- グループメンバー
- QueuesObject
- ユーザー
- USERROLE
- userterrity
- 地域
さらに、ユーザーとテリトリーは挿入および更新DML操作をサポートするようになり、UserroleがINSERT、UPDATE DELETE、UPSERT DML操作をサポートするようになりました。
Apex DML操作は、次のSobjectsではサポートされていません。
- accounterritoryAssignmentrule
- accountRitoryAssignmentRuleitem
- userAccountTeamMember
この動作は、実際にはSalesforceのドキュメントで文書化されています。 http://www.salesforce.com/us/developer/docs/apexcode/index_left.htm#starttopic=content/apex_dml_non_mix_sobjects.htm?searchtype. 。 「これの主な例外は、テストでRunasメソッドを使用している場合です」と言う場所を読んでください。
ドキュメントでこれを見つけたばかりです:
のその他の用途
runAs
使用することもできます
runAs
テストで混合DML操作を実行する方法DML操作を囲むことによりrunAs
ブロック。このようにして、セットアップオブジェクトを他のオブジェクトと一緒に挿入または更新するときに返される混合DMLエラーをバイパスしますsObjects
. 。見るsObjects
DML操作では一緒に使用することはできません。
だから RunAs
回避策は回避策ではありませんが、DMLの混合問題による唯一の進行方法としてSalesforceによって想定されています。
お役に立てれば
このエラーは、APEXでの単一のトランザクションでユーザーやその他のオブジェクトレコードを作成しようとする場合に非常に一般的です。
Apexクラス/トリガーでの回避策:エラーが発生したときにユーザーを作成するために将来の方法を使用する
テストクラスでの回避策:新しいユーザーデータを作成してみて、代わりに使用しないでください)>
code -snippetで -https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html