I’m performing an update from a ServiceBean which is inside a newly created transaction. I’m also populating some of the EntityManagerContext attributes as well so that the listener can pick them up. Everything was working fine, but now in production, intermittently the values don’t get passed to the listener and are causing problems. The system will then continue to create problems for the same user until we restart tomcat. Logging out then back in doesn’t fix the problem. Unfortunately I can’t reproduce the error, but I know that the attributes are being cleared out. Any suggestions? Any other way to move data from a serviceBean to the listener for a given transaction that I can try instead?
My process is:
Immediately before doing a merge (to do an update) in the ServiceBean I get the EntityManagerContext and set some attributes.
I perform the merge.
I redundantly get EntityManagerContext again here just in case and set the attributes again. But it still doesn’t help.
I commit the transaction.
The very first thing I do in the listener for Update is to get the EntityManagerContext and get the attributes. I know doing some other actions in the listener can wipe the values of the context so I always get the attributes before I do anything else.
Values are consistently there, except for a couple of users ever-so often in production.
Very frustrating. I’ll need to fix this and am looking for ideas. My approach for this was given to me from this post: Middleware Awareness.
I would suspect some bug in the framework if you didn’t mention that the problem keeps occurring for a particular user. This is really strange, and most probably caused by some application logic. The only thing that links EntityManagerContext with user sessions is the fact that both are set for the current thread in some ThreadLocal variables - EntityManagerContext for the duration of a transaction and UserSession for the whole request. I cannot imagine how one can affect the other.
To simplify things and to have everything under your control, instead of EntityManagerContext attributes you could use an own ThreadLocal variable. In fact, EntityManagerContext is stored in a ThreadLocal too, but it is also bound to a transaction and is replaced in case of start/end of nested transactions in the same thread. If you have a single uninterrupted transaction between writing and reading values, or you are sure that nested transactions don’t use the same variable, a simple ThreadLocal should work.
I was digging into my issue history. It looks like this was reported three times since we went to production 2 weeks ago. One user reported it twice and another reported it once. I believe it’s a framework issue because I have no logic in between the end of the bean service and the start of the listener. I am intrigued by the ThreadLocal idea and will look into it. This application has around 500-600 concurrent users at a time. I don’t work with the users directly and don’t know if they get this error more often or not and aren’t reporting it.