fix: Fix issues with replicating users#23150
Open
jason-p-pickering wants to merge 12 commits intomasterfrom
Open
fix: Fix issues with replicating users#23150jason-p-pickering wants to merge 12 commits intomasterfrom
jason-p-pickering wants to merge 12 commits intomasterfrom
Conversation
…o fix-replicate-users
…o fix-replicate-users
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Root Cause
replicateUserusedDefaultMetadataMergeService.merge()to clone the source user. The merge service guards every collection copy withHibernate.isInitialized()- silently skipping any collection that isn't already loaded in memory. Since the source User arrives from the controller as a detached entity, all lazy collections (roles, groups, org units, dimension constraints) are uninitialized, and the replica was created with none of them. This was noted due to failing tracker performance tests, and not DHIS2 integration tests.A secondary issue: owning-side collections (userRoles, organisationUnits, dataViewOrganisationUnits, teiSearchOrganisationUnits, cogsDimensionConstraints,catDimensionConstraints) written via raw JDBC after
session.persist()are invisible to the L1 cache without explicit eviction, causing stale reads immediately after replication.Solution
entityManager.flush()before JDBC so the new userinfo row is visible to the DBChanges
Known Limitations
Distributed cache (Redis): The post-JDBC cache eviction covers the Hibernate L1 session cache and the local L2 second-level cache. If a Redis-backed distributed cache is in use for user collection regions, those entries are not invalidated here. A subsequent read from a different node may return stale membership data until the TTL expires.
Temporary workaround: This PR works around the root cause rather than eliminating it. The correct long-term fix is to replace the
metadataMergeService.merge()call with a dedicatedUser.copyScalarFieldsFrom(User source)method that makes the clone contract explicit - only copying fields that are safe and meaningful to replicate, with nodependence on Hibernate initialization state.