[SalesForce] How to Upsert Hierarchy Custom Settings While Testing

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

Best Answer

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.

Related Topic