Dreaded NoSuchUserException while adding DDL records with JSON-WS

There is nothing worse than starting your day and being confronted with an error like this:

com.liferay.portlet.dynamicdatamapping.StorageException: com.liferay.portal.NoSuchUserException: No User exists with the primary key 0

I certainly *DO* exist, Liferay, and do not appreciate being assigned the number 0. wink

I received this error while trying to add a DDL record through JSON-WS with the method /ddlrecord/add-record on Liferay 6.1. 

Funnily enough, I had already had success with other method calls like /ddlrecordset/add-record-set so I was fairly confused as to how the user authentication was not working. In this case the JSON-WS call is being done through AJAX from a existing Liferay page, so I am using Liferay.authToken to authenticate which works perfectly.

This led me to a google search. Unfortunately, it appears that many people have had to deal with "No user exists.." but I could not find any concrete solutions for my problem. This forum message seemed to be exactly describe what I was experiencing:

https://www.liferay.com/community/forums/-/message_boards/view_message/71955777

After thinking a bit about how some calls could work and others not it seemed clear that the authentication was not the issue. Looking at the source to DDLRecordLocalServiceImpl made it clear that the method addRecord expects a userId while other methods like deleteRecord do not. Apparently somehow the userId is not getting passed in properly. 

Luckily in this case we can ask for help from our good friend serviceContext and pass in the userId that way: 

curl https://$SERVER/api/secure/jsonws/ddlrecord/add-record \
-u $USER:$PASSWORD \
-d serviceContext.userId=$USERID \
-d groupId=$GROUPID \
-d recordSetId=$RECORDSETID \
-d displayIndex=0 \
-d fieldsMap="{'link_name': 'test'}" \

Problem solved! I am not sure why this is not always necessary, but in case you run into the issue, you know what to do.

 

 

Blogs
This works beautifully using cur. Any idea how I would pass in that serviceContext.userId via a javascript post to ~/ddlrecord/add-record?
I should clarify that this is what I am trying to do:

Liferay.Service('http://localhost:9080/api/jsonws/ddlrecord/add-record', {
groupId: $groupId,
recordSetId: 11331,
displayIndex: 0,
fieldsMap: {'txtApplicantName':'Frodo Baggins'},
serviceContext: {
userId: 10434
}
},
function(obj) {
console.log(obj);
}
);
[...] Let me begin by clarifying that this post has nothing to do with the Harry Potter universe. But seriously. You know what I mean by wizards, don’t you? Those helpful series of screens that gather... [...] Read More