Model Listeners

Vivek Mehta, modified 6 Years ago. Junior Member Posts: 48 Join Date: 4/7/19 Recent Posts
Hi there,
I made  a model listener for on user update. But on updating a user, i want to store the user id of both the updated user as well  as the logged in user who is performing the operation. I am able to get the user id of the updated user but not of the  logged in user. Can anyone help me out please.
thumbnail
Andrew Jardine, modified 6 Years ago. Liferay Legend Posts: 2416 Join Date: 12/22/10 Recent Posts
Hi Vivek,

Not sure I have good news for you here -- though I'm not sure I even understand what you are asking. 
I want to store the user id of both the user and the user

.. So you want to store more than one user id is what I think you are saying. So when you say ..
I am able to get the user ID of the user updated but not of the logged in user.

.. I'm nto sure I follow. Isn't the user who is logged in the same user who is making the change? 

One thing to note here is that the model listeners don't run on the same request context as the orignal request that was making the model update. It happens as a separate process which is why you don't have access to the thread locals or any http request objects. Remember, they are observers, so they fire based on events, not on requests.

​​​​​​​
thumbnail
Christoph Rabel, modified 6 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
I think the idea is auditing. He wants to know, who has changed/updated a user. Maybe it was an admin/organization admin, ...
thumbnail
Andrew Jardine, modified 6 Years ago. Liferay Legend Posts: 2416 Join Date: 12/22/10 Recent Posts
Oh I see, yes you are totally right -- I misread the post. I think you are spot on Christoph in your advice to use a service wrapper. Model Listeners are the knee jerk reaction to use because they seem to make the most sense for this type of scenario, but the lack of service context (and empty thread local) throws a wrench into the mix. 

I know that Lifeary's own solution for audit definitely use a mix of plugin types, not just model listeners. For example, recording that someone has logged in to the system is done with a PostLogin event I believe.
thumbnail
Christoph Rabel, modified 6 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
I guess, you need to use a ServiceWrapper or something even higher up in the chain.
https://dev.liferay.com/de/develop/tutorials/-/knowledge_base/7-0/customizing-liferay-services-service-wrappers

In the servicewrapper you should be able to fetch the current user from the serviceContext.

 ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
 if (null != serviceContext) {
   long currentUserId = serviceContext.getUserId();
 } else {
// This could happen, when there is no request (e.g. in a scheduled job). I'd write a warning here in your case and monitor (or check manually for) that warning.
}



If the user is changed using the control panel (e.g. by an admin), you could probably override the relevant action.
https://dev.liferay.com/de/develop/tutorials/-/knowledge_base/7-0/overriding-mvc-commands