Details
-
Bug
-
Resolution: Fixed
-
Low
-
6.2.4
-
None
-
24
-
Severity 2 - Major
-
6
-
Description
When we try to import a space which have shadowed users in entities.xml, this might result to an error.
Suppose we have two users with the same username (one of them is shadowed).
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80836102bd4d016104a5e1de0072]]></id> <property name="name"><![CDATA[xxx4109]]></property> <property name="lowerName"><![CDATA[xxx4109]]></property> </object> <object class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80835f99e63b015f9c11a34e006a]]></id> <property name="name"><![CDATA[xxx4109]]></property> <property name="lowerName"/> </object>
In reality, the system won't import both of them. It will treat those users as the same because they have the same username. The piece of code responsible for it:
// Try to reuse existing user mapping objects when performing an incremental import if (!context.isPreserveIds() && classToPersist.equals(ConfluenceUserImpl.class)) { // Try to match using UUID if (confluenceUserDao.findByKey((UserKey) id) != null) { context.addExplicitIdMapping(unfixedHandle, id); return Collections.singletonList(unfixedHandle); } // Try to match using username String username = ((ConfluenceUser) objectToPersist).getName(); ConfluenceUser user = confluenceUserDao.findByUsername(username); if (user != null) { context.addExplicitIdMapping(unfixedHandle, user.getKey()); return Collections.singletonList(unfixedHandle); } }
This is a problem because if we had entries for both these users in the old system (for example in user relations)
<object class="User2ContentRelationEntity" package="com.atlassian.confluence.internal.relations.dao"> <id name="id">219546609</id> <property name="targetContent" class="Page" package="com.atlassian.confluence.pages"> <id name="id">27893032</id> </property> <property name="sourceContent" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80836102bd4d016104a5e1de0072]]></id> </property> <property name="targetType" enum-class="RelatableEntityTypeEnum" package="com.atlassian.confluence.internal.relations"> PAGE </property> <property name="relationName"><![CDATA[touched]]></property> <property name="creationDate">2018-04-20 14:44:59.037</property> <property name="lastModificationDate">2018-04-20 14:45:56.056</property> <property name="creator" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80836102bd4d016104a5e1de0072]]></id> </property> <property name="lastModifier" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80836102bd4d016104a5e1de0072]]></id> </property> </object> <object class="User2ContentRelationEntity" package="com.atlassian.confluence.internal.relations.dao"> <id name="id">91488312</id> <property name="targetContent" class="Page" package="com.atlassian.confluence.pages"> <id name="id">27893032</id> </property> <property name="sourceContent" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80835f99e63b015f9c11a34e006a]]></id> </property> <property name="targetType" enum-class="RelatableEntityTypeEnum" package="com.atlassian.confluence.internal.relations"> PAGE </property> <property name="relationName"><![CDATA[touched]]></property> <property name="creationDate">2018-01-17 17:09:26.374</property> <property name="lastModificationDate">2018-01-17 17:09:26.374</property> <property name="creator" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80835f99e63b015f9c11a34e006a]]></id> </property> <property name="lastModifier" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"> <id name="key"><![CDATA[8a7f80835f99e63b015f9c11a34e006a]]></id> </property> </object>
The system will try to insert both of them, but with the same user_key in sourceEntity (because it treats users with equal username as the same users). This will lead to unique key violation in usercontent_relations table:
UNIQUE KEY `u2c_relation_unique` (`TARGETCONTENTID`,`SOURCEUSER`,`RELATIONNAME`),
The import should not treat users with the same username as the same users because they are not. We have a notion of shadowed usernames and currently it fails the import, which should be fixed.
Notes
These are the common error logs you see related to this issue:
2022-04-03 18:43:41,930 ERROR [Long running task: Importing data] [engine.jdbc.spi.SqlExceptionHelper] logExceptions ERROR: duplicate key value violates unique constraint "unq_lwr_username" Detail: Key (lower_username)=() already exists.
2022-04-03 15:24:08,766 ERROR [Long running task: Importing data] [engine.jdbc.spi.SqlExceptionHelper] logExceptions ERROR: duplicate key value violates unique constraint "u2c_relation_unique" Detail: Key (targetcontentid, sourceuser, relationname)=(426886206, 8ad560a779e784fb017b30c921ef01dd, touched) already exists.