2

I'm trying to update custom settings in my class using the following:

public static CustSettings__c settings;
public static void updateSettings(){
    settings = CustSettings__c.getInstance();
    system.debug('before: ' + settings);
    if (settings.somevalue__c == NULL){
        settings.somevalue__c = 'XYZ';
        upsert settings;
        system.debug('after: ' + settings);
        }
    }

I get the following error:

16:57:40:631 EXCEPTION_THROWN [45]|System.DmlException: Upsert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: SetupOwnerId duplicates value on record with id: 00541000000qdYd: []

updateSettings() is called twice in my code path. The settings do get updated the first time but when the call comes in again, the settings object is empty and it tries do an upsert again where it throws the error.Is this the right way to update custom settings? Note: I'm trying to test this from my test class.

Edit: (Adding some more logs)

Adding before/after save values for settings object:

First call to updateSettings(): 

before:
16:57:40:377 USER_DEBUG [42]|DEBUG|settings: CustSettings__c:{SetupOwnerId=00541000000qdYdAAI}

after:
16:57:40:409 USER_DEBUG [46]|DEBUG|settings2: CustSettings__c:{SetupOwnerId=00541000000qdYdAAI, somevalue__c=ERROR, Id=a0H41000004UPKOEA4}

second call to updateSettings():

before:
16:57:40:617 USER_DEBUG [42]|DEBUG|settings: CustSettings__c:{SetupOwnerId=00541000000qdYdAAI}

--> throws the above mentioned error

Edit: Updated settings to show it is a static variable

4
  • Where are you getting that instance() method from? That shouldn't compile.
    – Adrian Larson
    Commented Jan 19, 2017 at 0:33
  • Sorry about that, it is getInstance(). Will update
    – gerad26
    Commented Jan 19, 2017 at 0:35
  • Is there any specific reason for you to use "upsert" instead of "update" ?
    – Varun
    Commented Jan 19, 2017 at 0:36
  • I'm trying to add the settings object if it is not present already and that is why I'm doing an upsert.
    – gerad26
    Commented Jan 19, 2017 at 0:42

3 Answers 3

4

Your problem, most likely, is that you ended up with a null SetupOwnerId. This appears to be a bug, because you're not supposed to have a null value. Make sure you're using getOrgDefaults instead of getInstance if you want the global value, and that you're not passing a null value to getInstance. In your unit test, make sure you set an org default.

10
  • I edited the post to include the entire log. I do see that the setupOwnerId is set. The issue is that the second time is is updated, it tries to update the setupOwnerId as well for some reason and throws that error.
    – gerad26
    Commented Jan 19, 2017 at 0:41
  • @gerad26 Hmm, what is the Id on the custom setting? The default mode for upsert is to use the Id field.
    – sfdcfox
    Commented Jan 19, 2017 at 0:42
  • Interestingly, the ID on the setting does not match the ID in the error log. I have the following log after the first commit- 16:15:19:269 USER_DEBUG [46]|DEBUG|settings: CustSettings__c:{somevalue__c=XYZ, Id=a0H41000004UOuaEAG}
    – gerad26
    Commented Jan 19, 2017 at 0:52
  • @gerad26 I kind of suspected as much. Are you trying to store a global value, or user-specific?
    – sfdcfox
    Commented Jan 19, 2017 at 1:03
  • I edited the question with new set of logs. I'm trying to store global values for custom settings. I changed how I was fetching custom settings to use getOrgDefaults(). I get the same error. However there is one change that the settings object does not have the setupOwnerId field. [ after save : 17:08:37:391 USER_DEBUG [46]|DEBUG| settings2: CustSettings__c:{somevalue__c=XYZ, Id=a0H41000004UPNWEA4} ] . But the error remains the same.
    – gerad26
    Commented Jan 19, 2017 at 1:11
1

In API version 42.0 and later, if a hierarchy custom setting is inserted in a testSetup method, inserting a hierarchy custom setting record with the same SetupOwnerId in a test method throws a DUPLICATE_VALUE exception. Hierarchy Custom Setting Methods

0

Possibly you are encountering the fact that static class-level variables in a test class are wiped out before each test method execution. The fact that it works in an anonymous execution, but not a test, points to this. (Why they do that? If the static variables persisted, they could could be changed by the test methods. That would create a dependency on the order of execution of the test methods; but the order cannot be controlled or predicted. A reset to original values would be more useful; it doesn't do that.)

You must log in to answer this question.

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