Uploaded image for project: 'Crowd Data Center'
  1. Crowd Data Center
  2. CWD-3147

If a user exists in two directories in an application, and is added to a group in one directory that it was already in the other, clients get duplicate key errors

    • Icon: Bug Bug
    • Resolution: Obsolete
    • Icon: Medium Medium
    • 2.8
    • 2.6.1, 2.7.2
    • None
    • None

      Symptoms

      In a client application, directory synchronisation fails with a duplicate key error, when adding a group membership. This will appear in the client log.

      Sample Confluence log:

      2013-02-20 15:49:36,071 ERROR [scheduler_Worker-4] [atlassian.crowd.directory.DbCachingDirectoryPoller] pollChanges Error occurred while refreshing the cache for directory [ 98307 ].
      org.springframework.dao.DataIntegrityViolationException: Hibernate operation: could not insert: [com.atlassian.crowd.embedded.hibernate2.HibernateMembership#295109]; SQL []; ERROR: duplicate key value violates unique constraint "cwd_unique_user_membership"
        Detail: Key (parent_id, child_user_id)=(163847, 229382) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "cwd_unique_user_membership"
        Detail: Key (parent_id, child_user_id)=(163847, 229382) already exists.
      	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:100)
      	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
      	at org.springframework.orm.hibernate.HibernateTransactionManager.convertJdbcAccessException(HibernateTransactionManager.java:619)
      	at org.springframework.orm.hibernate.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:605)
      	at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:518)
      	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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      	at com.atlassian.crowd.directory.$Proxy1476.addUserToGroup(Unknown Source)
      	at com.atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations.addUserToGroup(DirectoryCacheImplUsingChangeOperations.java:187)
      	at com.atlassian.crowd.directory.ldap.cache.EventTokenChangedCacheRefresher.synchroniseChanges(EventTokenChangedCacheRefresher.java:115)
      	at com.atlassian.crowd.directory.DbCachingRemoteDirectory.synchroniseCache(DbCachingRemoteDirectory.java:610)
      	at com.atlassian.crowd.manager.directory.DirectorySynchroniserImpl.synchronise(DirectorySynchroniserImpl.java:63)
      	at com.atlassian.crowd.directory.DbCachingDirectoryPoller.pollChanges(DbCachingDirectoryPoller.java:50)
      	at com.atlassian.crowd.manager.directory.monitor.poller.DirectoryPollerJobBean.executeInternal(DirectoryPollerJobBean.java:29)
      	at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
      	at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
      	at com.atlassian.confluence.schedule.quartz.ConfluenceQuartzThreadPool$1.run(ConfluenceQuartzThreadPool.java:20)
      	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
      Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "cwd_unique_user_membership"
        Detail: Key (parent_id, child_user_id)=(163847, 229382) already exists.
      	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
      	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
      	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
      	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
      	at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
      	at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:462)
      	at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:436)
      	at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:37)
      	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2464)
      	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2450)
      	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2407)
      	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2276)
      	at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
      	at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:510)
      	... 17 more
      

      Sample JIRA log:

      2013-02-20 15:49:35,363 QuartzWorker-0 ERROR ServiceRunner     [atlassian.crowd.directory.DbCachingDirectoryPoller] Error occurred while refreshing the cache for directory [ 10001 ].
      com.atlassian.jira.crowd.embedded.ofbiz.db.DataAccessException: org.ofbiz.core.entity.GenericEntityException: while inserting: [GenericEntity:Membership][id,10067][membershipType,GROUP_USER][lowerParentName,jira-users][parentId,10013][childId,10014][childName,dmason][lowerChildName,dmason][directoryId,10001][parentName,jira-users] (SQL Exception while executing the following:INSERT INTO public.cwd_membership (ID, parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) (ERROR: duplicate key value violates unique constraint "uk_mem_parent_child_type"
        Detail: Key (parent_id, child_id, membership_type)=(10013, 10014, GROUP_USER) already exists.))
      	at com.atlassian.jira.crowd.embedded.ofbiz.db.OfBizHelper.createValue(OfBizHelper.java:167)
      	at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.createMembership(OfBizInternalMembershipDao.java:101)
      	at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.addUserToGroup(OfBizInternalMembershipDao.java:94)
      	at com.atlassian.jira.crowd.embedded.ofbiz.OfBizDelegatingMembershipDao.addUserToGroup(OfBizDelegatingMembershipDao.java:78)
      	at com.atlassian.crowd.directory.AbstractInternalDirectory.addUserToGroup(AbstractInternalDirectory.java:695)
      	at com.atlassian.crowd.directory.DbCachingRemoteChangeOperations.addUserToGroup(DbCachingRemoteChangeOperations.java:1151)
      	at com.atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations.addUserToGroup(DirectoryCacheImplUsingChangeOperations.java:187)
      	at com.atlassian.crowd.directory.ldap.cache.EventTokenChangedCacheRefresher.synchroniseChanges(EventTokenChangedCacheRefresher.java:115)
      	at com.atlassian.crowd.directory.DbCachingRemoteDirectory.synchroniseCache(DbCachingRemoteDirectory.java:609)
      	at com.atlassian.crowd.manager.directory.DirectorySynchroniserImpl.synchronise(DirectorySynchroniserImpl.java:63)
      	at com.atlassian.crowd.directory.DbCachingDirectoryPoller.pollChanges(DbCachingDirectoryPoller.java:50)
      	at com.atlassian.crowd.manager.directory.monitor.poller.DirectoryPollerJob.execute(DirectoryPollerJob.java:34)
      	at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
      	at com.atlassian.multitenant.quartz.MultiTenantThreadPool$MultiTenantRunnable.run(MultiTenantThreadPool.java:72)
      	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
      Caused by: org.ofbiz.core.entity.GenericEntityException: while inserting: [GenericEntity:Membership][id,10067][membershipType,GROUP_USER][lowerParentName,jira-users][parentId,10013][childId,10014][childName,dmason][lowerChildName,dmason][directoryId,10001][parentName,jira-users] (SQL Exception while executing the following:INSERT INTO public.cwd_membership (ID, parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) (ERROR: duplicate key value violates unique constraint "uk_mem_parent_child_type"
        Detail: Key (parent_id, child_id, membership_type)=(10013, 10014, GROUP_USER) already exists.))
      	at org.ofbiz.core.entity.GenericDAO.singleInsert(GenericDAO.java:136)
      	at org.ofbiz.core.entity.GenericDAO.insert(GenericDAO.java:101)
      	at org.ofbiz.core.entity.GenericHelperDAO.create(GenericHelperDAO.java:64)
      	at org.ofbiz.core.entity.GenericDelegator.create(GenericDelegator.java:487)
      	at org.ofbiz.core.entity.GenericValue.create(GenericValue.java:98)
      	at com.atlassian.jira.crowd.embedded.ofbiz.db.OfBizHelper.createValue(OfBizHelper.java:162)
      	... 14 more
      

      This also happens when using JIRA as a user directory server for other applications.

      Cause

      The application in Crowd has multiple directories, and a user name exists in both directories. When a user is a member of a group in one directory, then added to the same named group in the other directory, then when clients synchronise again, they try to add the user to that group. Since that user is already a member of the group, it's a duplicate key error.

      Steps to Reproduce

      1. Create two internal directories in crowd
      2. Create a user in each of them, with the same name
      3. Create a group in both directories
      4. Add the user to a group in one of the directories
      5. Add an application that includes both directories
      6. Connect a client to that application in the Crowd server
      7. Ensure it synchronises at least once
      8. Add the user to the same group in the directory where it didn't already have that membership
      9. Synchronise the client again

      Workaround

      Two ways to prevent it from occurring:

      1. Ensure that there are no overlaps in usernames between directories, or ensure that groups are not added when the membership already exists in one directory (process change). This may be hard to manage if one of the directories is an LDAP synchronised directory, or synchronised from another Crowd server out of the control of the administrator.
      2. Create two applications, each with only one of the directories in them. Then set up two user directories in the client instead. This does not work, if JIRA is the Crowd server, as JIRA simply uses all directories whenever a client connects in.

      If it does occur in the client, you can clear the remote directory cache to stop it from happening until the next time a user is added to a group this way:

      1. Disable the directory
      2. Enable the directory
      3. Force a full synchronisation

          Form Name

            [CWD-3147] If a user exists in two directories in an application, and is added to a group in one directory that it was already in the other, clients get duplicate key errors

            Occurs in 5.2.0

            Tommy van Extel added a comment - Occurs in 5.2.0

            Occurs in 4.2.2.

            Karen Mixon added a comment - Occurs in 4.2.2.

            3.5.1 here and 180 matches in the logs appeared in the last 48 hours

            Deleted Account (Inactive) added a comment - 3.5.1 here and 180 matches in the logs appeared in the last 48 hours

            3.4.0 also :/

            Andrzej Talarek added a comment - 3.4.0 also :/

            And apparently in 3.0.1

            Deleted Account (Inactive) added a comment - And apparently in 3.0.1

            Andy Smith added a comment -

            Occurs in Crowd 2.12.0 also

            Andy Smith added a comment - Occurs in Crowd 2.12.0 also

            Uhub Admin added a comment -

            Running Crowd 2.8.2 and the Support Tools log scanner links me to this ticket - apparently solved in 2.8, so either a regression, new similar issue, or the Log analyzer is mis-matching cause and effect

            Uhub Admin added a comment - Running Crowd 2.8.2 and the Support Tools log scanner links me to this ticket - apparently solved in 2.8, so either a regression, new similar issue, or the Log analyzer is mis-matching cause and effect

            Arjay relucio

            Arjay Relucio added a comment - Arjay relucio

            Hi Sunny,

            I am using Crowd 2.8.2 as well - i upgraded it to this thinking the bug would be solved as I initially saw it in 2.7.1. I have raised a bug/support request regarding groups getting removed but have had no response. CWDSUP-10647. I guess I shall try this after I get a resolution for the initial request.

            Thanks
            Anand

            Anand Unadkat added a comment - Hi Sunny, I am using Crowd 2.8.2 as well - i upgraded it to this thinking the bug would be solved as I initially saw it in 2.7.1. I have raised a bug/support request regarding groups getting removed but have had no response. CWDSUP-10647. I guess I shall try this after I get a resolution for the initial request. Thanks Anand

            Hi Anand,

            Whatever you're encountering sounds like a different bug. Specifically, I suspect it's being caused by whatever is happening in the first half (the groups being removed). If you are having this problem, please raise a support request, and they will walk you through to see if this could be a configuration issue or a bug, the nature of the bug, and any workarounds.

            FWIW I tried to reproduce this but could not, and also my groups were not being removed as they were for you. I was using Crowd 2.8.2 and MySQL 5.6.24.

            Thanks for the extra information Anand.

            Sunny Kalsi [Atlassian] added a comment - Hi Anand, Whatever you're encountering sounds like a different bug. Specifically, I suspect it's being caused by whatever is happening in the first half (the groups being removed). If you are having this problem, please raise a support request, and they will walk you through to see if this could be a configuration issue or a bug, the nature of the bug, and any workarounds. FWIW I tried to reproduce this but could not, and also my groups were not being removed as they were for you. I was using Crowd 2.8.2 and MySQL 5.6.24. Thanks for the extra information Anand.

            Hi Sunny,

            Thanks for you comment.

            To answer your questions:

            • I am using MySQL
            • It does happen to all users
            • Not that I know of
            • Happens when I try to add groups to the users

            Regards
            Anand

            Anand Unadkat added a comment - Hi Sunny, Thanks for you comment. To answer your questions: I am using MySQL It does happen to all users Not that I know of Happens when I try to add groups to the users Regards Anand

            Hi anand.unadkat, thanks for the report. I just have a couple of follow-on questions:

            • Are you using MySQL?
            • Does this happen for all users?
            • If not, does the membership in LDAP have a trailing space on the username for which it happens?
            • When does the error occur? Does it happen during sync, for example?

            Sunny Kalsi [Atlassian] added a comment - Hi anand.unadkat , thanks for the report. I just have a couple of follow-on questions: Are you using MySQL? Does this happen for all users? If not, does the membership in LDAP have a trailing space on the username for which it happens? When does the error occur? Does it happen during sync, for example?

            For me, I still get this error.

            Steps to reproduce:

            • Add Crowd Internal Directory
            • Add all your users to it
            • Change the username (groups will disappear - this is another bug I believe)
            • Add LDAP directory which contain same usernames and add it to the application as well
            • Add groups to LDAP users
            • Add groups to Crowd internal user and error comes back
              org.springframework.dao.DataIntegrityViolationException: could not perform addBatch; SQL [insert into cwd_membership (parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; constraint [parent_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not perform addBatch 
              

              Regards

            Regards
            Anand

            Anand Unadkat added a comment - For me, I still get this error. Steps to reproduce: Add Crowd Internal Directory Add all your users to it Change the username (groups will disappear - this is another bug I believe) Add LDAP directory which contain same usernames and add it to the application as well Add groups to LDAP users Add groups to Crowd internal user and error comes back org.springframework.dao.DataIntegrityViolationException: could not perform addBatch; SQL [insert into cwd_membership (parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; constraint [parent_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not perform addBatch Regards Regards Anand

            I have tested and confirmed that this issue no longer occurs in Crowd 2.8.

            Denise Unterwurzacher [Atlassian] (Inactive) added a comment - I have tested and confirmed that this issue no longer occurs in Crowd 2.8.

            eddiewebb, we need more details about your configuration to investigate the problem and determine whether there is a regression here. May I suggest that you contact Support to open a ticket, and attach there some essential information, such as product versions and the "Directory configuration summary" (Administration > System information) screen in Crowd?

            Diego Berrueta added a comment - eddiewebb , we need more details about your configuration to investigate the problem and determine whether there is a regression here. May I suggest that you contact Support to open a ticket, and attach there some essential information, such as product versions and the "Directory configuration summary" (Administration > System information) screen in Crowd?

            EddieW added a comment -

            I disagree that CWD-3188 addresses this issue at all. We are on the latest of all 3 tools (JIRA, Confluence, Crowd) and still would get this error, and no full sync would occur.

            Our only resolution was to update the underlying LDAP rules for the directories in Crowd to be mutually exclusive.
            Directory 1:
            (memberof=thisisatrivialexample)
            Directory 2:
            (!(memberof=thisisatrivialexample))

            This allowed both JIRA and Confluence to sync without issue.

            EddieW added a comment - I disagree that CWD-3188 addresses this issue at all. We are on the latest of all 3 tools (JIRA, Confluence, Crowd) and still would get this error, and no full sync would occur. Our only resolution was to update the underlying LDAP rules for the directories in Crowd to be mutually exclusive. Directory 1: (memberof=thisisatrivialexample) Directory 2: (!(memberof=thisisatrivialexample)) This allowed both JIRA and Confluence to sync without issue.

            The fix for CWD-3188 reduces the severity of the problem, since failed incremental synchronisation now immediately fallbacks to full sync, without the need to implement any workaround. After the successful full sync, the sync will revert to incremental again, also automatically.

            A "duplicate key" exception may still be logged, but it will not prevent the sync from completing successfully.

            I keep the issue open because the root cause of the problem still persists, i.e., Crowd still generates a "membership added" event that is inconsistent with the client state. Note, however, that it does not cause any serious harm to Jira/Confluence (if they contain the fix for CWD-3188) besides the exception in the logs and the performance penalty associated with falling back to a full sync (just once).

            Diego Berrueta added a comment - The fix for CWD-3188 reduces the severity of the problem, since failed incremental synchronisation now immediately fallbacks to full sync, without the need to implement any workaround. After the successful full sync, the sync will revert to incremental again, also automatically. A "duplicate key" exception may still be logged, but it will not prevent the sync from completing successfully. I keep the issue open because the root cause of the problem still persists, i.e., Crowd still generates a "membership added" event that is inconsistent with the client state. Note, however, that it does not cause any serious harm to Jira/Confluence (if they contain the fix for CWD-3188 ) besides the exception in the logs and the performance penalty associated with falling back to a full sync (just once).

            Jira 5.2.10 already fixed this but this doesn't mean that this bug doesn't have to be fixed. Crowd is not only about Jira.

            Sorin Sbarnea added a comment - Jira 5.2.10 already fixed this but this doesn't mean that this bug doesn't have to be fixed. Crowd is not only about Jira.

            When on boarding users, you have to do this workaround multiple times a day. Also, it seems this essentialy breaks Crowd as a single central directory of users for a suite of atlassian apps.

            I'd bump this to critical.

            James Kyle added a comment - When on boarding users, you have to do this workaround multiple times a day. Also, it seems this essentialy breaks Crowd as a single central directory of users for a suite of atlassian apps. I'd bump this to critical.

            As a note, the workaround is almost useless as it requires manual intervention (directory enable/disable/sincronize) every time this happens, and this happens quite often (every 2-3 day).

            Sorin Sbarnea added a comment - As a note, the workaround is almost useless as it requires manual intervention (directory enable/disable/sincronize) every time this happens, and this happens quite often (every 2-3 day).

            I would raise the severity of the issue as this bug will break crowd synchronizations and new accounts will be prevented from logging in.

            Sorin Sbarnea added a comment - I would raise the severity of the issue as this bug will break crowd synchronizations and new accounts will be prevented from logging in.

              Unassigned Unassigned
              dmason David Mason (Inactive)
              Affected customers:
              21 This affects my team
              Watchers:
              41 Start watching this issue

                Created:
                Updated:
                Resolved: