Uploaded image for project: 'Confluence'
  1. Confluence
  2. CONF-12201

Race condition issue with DefaultHibernateUser

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 2.8
    • Fix Version/s: 3.5
    • Component/s: None
    • Last commented by user?:
      true
    • Internal Complexity:
      4
    • Internal Value:
      4

      Description

      While debugging an issue in our custom authenticator that creates and updates user accounts during logins, I found something that appears to be a bug in how DefaultHibernateUser objects are being handled (and cached?) in confluence.

      It looks like the DefaultHibernateUser objects are being cached with its (groups) collections attached with the hibernate session that performed an operation on the object recently (in a different thread). When another thread with a new hibernate session attempts to update such a user instance the exception below is thrown. We are not passing the objects between threads via http session or in any other way. Each thread obtains an instance of the user class via userAccessor.

      Steps to reproduce:

      You need two threads that get the user instance via an instance of UserAccessor, and call UserAccessor#saveUser(confUser).

      1. thread 1 opens a hibernate session
      2. thread 2 opens a hibernate session
      3. thread 1 fetches a user
      4. thread 1 saves the user
      5. thread 2 fetches the same user as thread #1
      6. thread 2 saves the user
      7. the exception is thrown in thread 2
      8. thread 1 closes the hibernate session - this is important, it seems that if the session was closed before thread 2 called saveUser, everything would be ok
      9. thread 2 closes the hibernate session

      The exception:

      org.springframework.orm.hibernate.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; 
      nested exception is net.sf.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
      Caused by: net.sf.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
              at net.sf.hibernate.collection.PersistentCollection.setCurrentSession(PersistentCollection.java:257)
              at net.sf.hibernate.impl.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:38)
              at net.sf.hibernate.impl.AbstractVisitor.processValue(AbstractVisitor.java:69)
              at net.sf.hibernate.impl.AbstractVisitor.processValues(AbstractVisitor.java:36)
              at net.sf.hibernate.impl.AbstractVisitor.process(AbstractVisitor.java:91)
              at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:1466)
              at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1480)
              at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1403)
              at org.springframework.orm.hibernate.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:604)
              at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:370)
              at org.springframework.orm.hibernate.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:601)
              at com.atlassian.user.impl.hibernate.HibernateUserManager.saveUser(HibernateUserManager.java:171)
              at com.atlassian.user.impl.cache.CachingUserManager.saveUser(CachingUserManager.java:143)
              at com.atlassian.user.impl.delegation.DelegatingUserManager.saveUser(DelegatingUserManager.java:144)
              at bucket.user.DefaultUserAccessor.saveUser(DefaultUserAccessor.java:224)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:296)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
              at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:20)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
              at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
              at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
              at $Proxy22.saveUser(Unknown Source)
              at com.sun.dse.wikis.auth.ConfluenceUserManager$1.doInHibernate(ConfluenceUserManager.java:96)
              at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:370)
              at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:337)
              at com.sun.dse.wikis.auth.ConfluenceUserManager.updateUser(ConfluenceUserManager.java:79)
              at com.sun.dse.wikis.auth.SsoFilter.doFilter(SsoFilter.java:124)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:217)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:185)
              at com.atlassian.confluence.util.ClusterHeaderFilter.doFilter(ClusterHeaderFilter.java:35)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:217)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:185)
              at org.springframework.orm.hibernate.support.OpenSessionInV
      

        Attachments

          Activity

            People

            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Last commented:
                5 years, 20 weeks ago