Symptom
When attempting to create a new User via OData API upsert, the following error is returned:
<d:editStatus m:null="true"></d:editStatus>
<d:message>Exception caught when saving user <userId>: Exception caught: com.successfactors.sca.service.exception.ServiceCreateFailedException: can not get personId. with the index 0</d:message>
<d:index m:type="Edm.Int32">0</d:index>
<d:httpCode m:type="Edm.Int32">500</d:httpCode>
NOTE: Image/data in this KBA is from SAP internal systems, sample data, or demo systems. Any resemblance to real data is purely coincidental.
Environment
- SAP SuccessFactors HXM Suite
- OData API
Cause
Let's say you're upserting a new user with user ID 97979797 via OData API:
POST https://<yourAPIURL>/odata/v2/upsert
{
"__metadata": {
"uri": "User",
"type": "SFOData.User"
},
"userId": "97979797",
"status": "t",
"username":"test"
}
- https://<yourAPIURL>/odata/v2/PerPerson('97979797')?$format=json&$expand=employmentNav/userNav&$select=employmentNav/userNav/userId
This returned the following result:
Resolution
There are three possible approaches to eliminate this error (approach 1 and 2 will have the exact same outcome/effect, only the method is different):
- Change the personIdExternal of the existing user via API upsert so that it becomes free for the new User you're trying to upsert;
- Change the personIdExternal of the existing user via file import so that it becomes free for the new User you're tying to upsert;
- Create the new user via file import, specifying a 'PERSON_ID_EXTERNAL' value which is not yet taken by any existing user.
Approach 1: Change the personIdExternal of the existing user via API upsert so that it becomes free for the new User you're trying to upsert
Changing the personIdExternal of an existing User might have an impact on business processes, especially if you're integrating the user to other systems, so it's important to evaluate this solution with care.
Going through the resolution steps, I'll use the same context as the example from the 'Cause' section (User with userId 97979797 can't be upserted because a PerPerson record with personIdExternal 97979797 already exists and is associated to userId 103331):
- Ideally we should change the PerPerson record of User 103331 to have a personIdExternal value that's equal to the userId (103331), so we should first check if there's another existing PerPerson record with that personIdExternal by performing a query:
GET https://<yourAPIURL>/odata/v2/PerPerson('103331')?$format=json - If the following response is returned, it means that personIdExternal 103331 is free and we can use it: "Entity PerPerson with the given key is not found."
- If the personIdExternal is free, the following upsert should be performed to change the personIdExternal from 97979797 to 103331:
{
"__metadata": {
"uri": "https://apisalesdemo4.successfactors.com:443/odata/v2/PerPerson('103331')",
"type": "SFOData.PerPerson"
},
"userId": "103331"
} - Now, we'll be able to upsert the new User with userId 97979797, because there's no PerPerson record with personIdExternal 97979797 anymore.
Approach 2: Change the personIdExternal of the existing user via file import so that it becomes free for the new User you're tying to upsert;
You can achieve the same effect as approach 1 by modifying the existing user record via file import:
- Go to Admin Center -> Employee Export;
- On 'Specify Export Options', mark the checkbox 'Include additional identifiers';
- Click on 'Export Users';
- Open the exported file and search (Ctrl+F) for the existing row with the PERSON_ID_EXTERNAL that's blocking the creation of your new user;
- Also search for the new PERSON_ID_EXTERNAL which you intend to attribute to the existing person, to make sure it's free to use and not taken by any other user;
- Delete all the rows from the CSV, except for the one which you found that has the PERSON_ID_EXTERNAL equal to the userId you're trying to upsert;
- Modify the PERSON_ID_EXTERNAL field value to the new one which you chose and ensured isn't assigned to any other user.
- Save the file;
- Go to Admin Center -> Import Employee Data;
- Select the action 'Import Data' and the 'Basic Import' entity;
- Upload the file saved on step 7, validate and import.
Approach 3: Create the new user via file import, specifying a 'PERSON_ID_EXTERNAL' value which is not yet taken by any existing user.
If you don't want to modify the personIdExternal of any existing records, you can simply create the new User via file import, passing a PERSON_ID_EXTERNAL value that's not being used:
- Go to Admin Center -> Import Employee Data
- Select Download Template and Basic Import
- Open the downloaded file;
- Edit the headers to leave only the fields that are required, PERSON_ID_EXTERNAL and the ones you want;
- Below the headers, fill the line with the new user's data and save;
- Back in SuccessFactors, select Import Data and Basic Import;
- Upload the file that was edited on steps 4 and 5;
- Validate the file and import.
Should none of the above workarounds be suitable, please note a request is being considered by our Development team for a permanent solution in the future (no ETA, our own internal reference: API-26057). Please keep an eye on this KBA for any updates on this.
See Also
Keywords
cannot, can't, not, working, able, successful, unsuccessful, unable, failed, failing, fails, error, issue, message, throws, throwing, returning, returns, rejecting, rejects, problem, wrong, SF, successfactors, Integration, flow, replication, replicate, data, Odata, api, request, call, query, upsert, insert, get, post, payload, response, create, creating, inserting , KBA , LOD-SF-INT-ODATA , OData API Framework , LOD-SF-INT , Integrations , Problem