4

Per the Apex doc - you can set DMLOptions either on the sobject directly or via the dmlOptions parameter of the Database.XXX methods

You can specify DML options for insert and update operations by setting the desired options in the Database.DMLOptions object. You can set Database.DMLOptions for the operation by calling the setOptions method on the sObject, or by passing it as a parameter to the Database.insert and Database.update methods.

But in my experience, at least for the DuplicateRuleHeader, you have to use the Database.xxx methods. Here's my example:

Assumes you have standard Lead Duplicate rules active as action=alert

Lead lead0 = new Lead(FirstName = 'Fred', LastName = 'Washington', Company = 'Foo', Email = '[email protected]');
insert lead0;  // save a Lead that will cause next lead to be a dup


Lead lead1 = lead0.clone();  // candidate duplicate
Database.SaveResult sr = Database.insert(lead1,false);
System.assertEquals(System.StatusCode.DUPLICATES_DETECTED,sr.getErrors()[0].getStatusCode(),
                   'sb a dup, our dup rules active and working as expected');

// Now, bypass dup rule alerts using dmlOptions as second arg of Database.insert
Database.DMLOptions dmlOptions = new Database.DMLOptions();
dmlOptions.DuplicateRuleHeader.allowSave = true;  // bypass dup rules on save
dmlOptions.DuplicateRuleHeader.runAsCurrentUser = true;

sr = Database.insert(lead1,dmlOptions);
System.assertEquals(true,sr.isSuccess(), // this passes as expected
     'lead1 should save now w/ dup rules bypassed via DmlOptions header');

//  Now, set DML options directly on the sobject
Lead lead2 = lead0.clone();
lead2.setOptions(dmlOptions);  // the setOptions way per doc
sr = Database.insert(lead2,false); // try and insert, should work
System.assertEquals(true,sr.isSuccess(),
                   'lead2 should save now w/ dup rules bypassed via DmlOptions header');

The last assertion fails. Note that insert lead2; also fails.

FATAL_ERROR|System.AssertException: Assertion Failed: 
 lead2 should save now w/ dup rules bypassed via DmlOptions header: Expected: true, Actual: false

I'll admit the example of setting DmlOptions for DuplicateRules in the doc use the Database.insert(lead2,dmlOptions) but the statement at the top of this post says both approaches should work.

Why would the DuplicateRuleHeader dmloptions NOT WORK with the sobject.setOptions(dmlOptions) method?

1 Answer 1

3

This is a bug and is noted in this known issue

Unable to save Duplicate records when we set DuplicateRuleHeader.AllowSave to True from Apex

The workaround mentions what you noted (that it works with Database.insert)

The issue is reproducible only when you assign DML options to SObjects rather than include them as in input for database.insert

4
  • looks like a V54 error as it is pretty recent? I could see a lot of code failing all of a sudden
    – cropredy
    Commented Apr 20, 2022 at 23:34
  • @cropredy I've found the setOptions on sObject has been unreliable for ages. I'm surprised nobody's reported this until now.
    – sfdcfox
    Commented Apr 20, 2022 at 23:36
  • Known issue was created in October 2021/Winter '22 (doesn't necessarily mean that's when it started - just when it was reported/created) Commented Apr 20, 2022 at 23:38
  • This reminds me of the inconsistent behaviour of UserRecordAccess, where direct table query combines CRUD perms and Sharing into the result while via SObject only considers Sharing.
    – Phil W
    Commented Apr 21, 2022 at 6:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .