Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: onUpdate(DLFileEntry) listener !!
Hi all!!I am using liferay 6.2 CE. I was tracking the action of user. Everything worked fine till I reached adding file model listener. When i am updating or creating a file then the listeners afterUpdate() and afterCreate() are working fine. But when i am downloading a file or document then also the afterUpdate() is being called. So, is there a way i can track whether i am downloading a file or updating it. Also in case of downloading, when i am using " GetterUtil.getLong(PrincipalThreadLocal.getName()); " to get the current user id , it is returnig 0. So, I would be glad if anyone could help me out.
Vivek Mehta:
Not sure if this pointer helps: I'm assuming that the update after download is caused by the view counter being incremented. If I remember correctly, this can be configured in portal-ext.properties. If you want to track downloads through a model listener, you'll need to determine if the view counter changed (this will be your pointer for a download) or if content changed.
when i am downloading a file or document then also the afterUpdate() is being called. So, is there a way i can track whether i am downloading a file or updating it.
Alternatively, if the view counter isn't incremented, I'd recommend to audit downloads from higher up the chain, e.g. through the web layer that actually handles the download. Because the ModelListener will only see changes, not access to an object.
Thanks Olaf,getReadCount() gets updated when we download a file. Actually previously i was implementing this in onAfterUpdate() listener, so it was giving both old and new read count as modified. Now i used onBeforeMethod() and now I am able to get both old and new readCount and tell whether the file is being updated or downloaded. This issue is solved. But the main problem I am facing is in getting userId when I am downloading a file. It is always giving userId as 0 and throwing no such user exception. Whereas , it is workking fine when I am normally updating the file.
I think, you need to implement a service wrapper for that. The listener is in a different thread than the update and the information is simply not there.
Hi Christoph,I used your method and tried to fetch the userId using service wrappers, but in this case also I was getting "0" only. So I tried one way :-
I made global variable "globalUserId" and fetched the userId in this variable when the user logs in. And now this global variable can be used anytime and anywhere required. But when I tried fetching this id in the login.pre / login.post hook it was giving the user Id of default liferay admin and not the current logged in user. So, I notice that afterUpdate() function was being called even when the user logs in. So I tried fetching the userId in this afterUpdate(User user) model listener and it workssss just perfectly now. But, I want to know Is it ok the way I have implemented it using the model listener or it can cause issues.
I made global variable "globalUserId" and fetched the userId in this variable when the user logs in. And now this global variable can be used anytime and anywhere required. But when I tried fetching this id in the login.pre / login.post hook it was giving the user Id of default liferay admin and not the current logged in user. So, I notice that afterUpdate() function was being called even when the user logs in. So I tried fetching the userId in this afterUpdate(User user) model listener and it workssss just perfectly now. But, I want to know Is it ok the way I have implemented it using the model listener or it can cause issues.
I don't think your approach will work. What happens if multiple user login. The global variable will only hold the id of the last user.
Are you sure that you don't get the user in the servicewrappers?
You should be able to do something like this to get the user:
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
// Note: Test for serviceContext == null here
long userId = serviceContext.getUserId();
Are you sure that you don't get the user in the servicewrappers?
You should be able to do something like this to get the user:
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
// Note: Test for serviceContext == null here
long userId = serviceContext.getUserId();
Hi Christoph,
I am afraid you are correct. I only thought about condition when someone logs in from one system only. So i set that global variable to "0" when the user logs out. But now if different users logs in from several systems, it will surely take the last logged in user only. I need to change the code again now
I am afraid you are correct. I only thought about condition when someone logs in from one system only. So i set that global variable to "0" when the user logs out. But now if different users logs in from several systems, it will surely take the last logged in user only. I need to change the code again now

And I am getting NULL for "serviceContext".
I think, you need to implement a service wrapper for that. The listener is in a different thread than the update and the information is simply not there.This isn't correct. See update(T model) in https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/service/persistence/impl/BasePersistenceImpl.java#L524. It calls modelListener in the same thread. You should be able to even throw an exception to rollback the transaction in the modelListener.
The thread spawn off should be in incrementViewCounter by the @BufferedIncrement annotation. So to catch the original thread, you'll have to go before this which is probably getFile or getFileAsStream. But I think I'd agree with Olaf though and go up even higher in the chain to the portlet.
Hah.
I didn't expect that. I was always under the assumption that the ModelListeners were "separated" and anything that happens there would not be able to affect the transaction. I am not sure, I am happy with that behavior, but it is as it is.
I didn't expect that. I was always under the assumption that the ModelListeners were "separated" and anything that happens there would not be able to affect the transaction. I am not sure, I am happy with that behavior, but it is as it is.
Hey Amos,
As I am typing this I realized that I can look at the git history on the file, but I am wondering if you know off hand when this change came into effect. I ask because I normally take the same path that Christoph suggested ... if you need the service context, use a wrapper (I mean that is not the only deciding factor, but a great "initial" vetting). With this, I would assume then that I would be able to access the ServiceContext using the ServiceContextThreadLocal in the model listener, something that previously evaluated to null because of course it was running on a separate thread where the thread local had not be initialized.
So does this mean that Service Context can actually be pulled in when working with model listeners now!?
As I am typing this I realized that I can look at the git history on the file, but I am wondering if you know off hand when this change came into effect. I ask because I normally take the same path that Christoph suggested ... if you need the service context, use a wrapper (I mean that is not the only deciding factor, but a great "initial" vetting). With this, I would assume then that I would be able to access the ServiceContext using the ServiceContextThreadLocal in the model listener, something that previously evaluated to null because of course it was running on a separate thread where the thread local had not be initialized.
So does this mean that Service Context can actually be pulled in when working with model listeners now!?

I think it has always been this way?
https://github.com/liferay/liferay-portal/commit/4151e0da9fc30806bcb3f81f8a15867b17228984
https://github.com/liferay/liferay-portal/commit/4151e0da9fc30806bcb3f81f8a15867b17228984
So does this mean that Service Context can actually be pulled in when working with model listeners now!?I just tested in 7.2 and it's not null

:| .. ok, I must be thinking of something else then. Maybe I was confusing it with the message listeners. At any rate, good to know that it's an option!

Hi,
Thanks everyone for your help.I solved this issue using the doFilter () method
doFilter() method will get called very first when we download a file and from there i am sending the userId of the user through the jsonws
Thanks everyone for your help.I solved this issue using the doFilter () method


Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™