-
1. Re: Custom Revision Listener - Getting user related information
adamw Nov 8, 2011 5:44 AM (in response to minajagi)1 of 1 people found this helpfulThe not-so-nice approach, but working, is to use a ThreadLocal (that's in fact how all static lookups in Weld or such work).
Alternatively, you can get the current revision entity from the AuditReader.
Adam
-
2. Re: Custom Revision Listener - Getting user related information
minajagi Nov 8, 2011 5:43 PM (in response to adamw)Thanks Adam,I did the same and then realised it is rather easier/safer to rely on Springcontext rather than my own ThreadLocal variable.
So,modified the LoginFilter that we had to add the Principal there and then in my listener use
Springcontextholder.getContext().getAuthentication() to
1) get the Principal
2)typecast to my UserInfo object and
3) finally get the user attribute that I'm interested in.
Regards,
Chetan
-
3. Re: Custom Revision Listener - Getting user related information
minajagi Jan 30, 2012 11:28 AM (in response to minajagi)I have a new problem now.Haven't still got to the the root of it.While i had all of this working,a few team members introduced one more step in the save and on their branch of code Envers Auditing fails always.The root cause is a Nullpointer exception in my RevisionListener where I do a SecurityContextHolder.getContext().getAuthentication().
The authentication object is null.
Interestlingly,since I couldn't trace any kind of conflicts/bugs that may have been introduced in the new changes I mentioned earlier on,I added a SecurityContext.setStrategy(THREADMODE_INHERITABLE).
With this stratgey I don't get any null pointer now.So my hunch is that Envers auditing code is executed by a seperate thread and hence the ThreadLocal Authentication object was null.
Is this how Envers works?
I had it working before without having to set the strategy as I have done now.
Any pointers will be a great help.
Here is the stack trace for your reference
----------------------------------------------------------------------------------------------------------------------------------------------
ERROR 2012-01-27 16:15:18,617 [Thread-27] (org.hibernate.AssertionFailure) - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
java.lang.NullPointerException
at com.mycomp.dealworks.domain.DWRevisionListener.getLoggedInUserSid(DWRevisionListener.java:47)
at com.mycomp.dealworks.domain.DWRevisionListener.newRevision(DWRevisionListener.java:33)
at org.hibernate.envers.revisioninfo.DefaultRevisionInfoGenerator.generate(DefaultRevisionInfoGenerator.java:86)
at org.hibernate.envers.synchronization.AuditProcess.getCurrentRevisionData(AuditProcess.java:121)
at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:104)
at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:143)
at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:138)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Regards,
Chetan
-
4. Re: Custom Revision Listener - Getting user related information
adamw Jan 31, 2012 3:06 PM (in response to minajagi)You should see if it's the same thread or not from the stack trace. Normally it is the same thread - I haven't seen it implemented otherwise yet. Maybe Spring already clears some contexts?
Adam
-
5. Re: Custom Revision Listener - Getting user related information
minajagi Feb 9, 2012 10:17 AM (in response to adamw)Yes you are right.Nothing wrong with Spring.We were the culprits again.There was an explicit Thread being spawned for the save to show some progress bar (to allow for some documents that are uploaded also to be stored in a seperate thread).This thread was actually incharge of the entire save and as such the spawned thread did not have access to the SecurityContext.
Having got to this point and realised why the null pointer was happening, we spotted that SecurityContext has a strategy that allows for spawned threads to inherit ThreadLocal objects from their parent threads.
So finally ended up adding a ContextListener to web.xml,that sets this strategy on the SecurityContextHolder.
Now it works like a charm again.
-Chetan
-
6. Re: Custom Revision Listener - Getting user related information
adamw Feb 10, 2012 4:49 PM (in response to minajagi)Great! Happy to hear that
Adam