Skip to content

backport: fix: Only apply the difference when replacing collection items [DHIS2-22217] - #25492

Merged
jason-p-pickering merged 1 commit into
2.43from
fix/DHIS2-22217-collection-replace-diff_2.43
Oct 7, 2026
Merged

jason-p-pickering merged 1 commit into
2.43from
fix/DHIS2-22217-collection-replace-diff_2.43

Conversation

@jason-p-pickering

Copy link
Copy Markdown
Contributor

…-22217] (#25479)

* fix: Only apply the difference when replacing collection items [DHIS2-22217]

PUT /api/{type}/{uid}/{property} removed every item in the collection and
then added every requested item back, even when the list was unchanged.
For non-owned collections such as OrganisationUnit.dataSets and
OrganisationUnit.programs, each touched item loads and updates its full
owning collection (DataSet.sources, Program.organisationUnits). On a large
instance, re-sending an org unit's unchanged data sets loaded hundreds of
thousands of org units, took 4 to 9 s, set a new lastUpdated on every data
set and program, and failed with HTTP 500 when the transaction hit the idle
in transaction timeout. The Metadata Management app sends these PUTs on
every org unit save.

replaceCollectionItems now compares the current and requested UIDs and
only removes and adds the difference, so an unchanged list touches nothing.
The collection endpoints also only clear the Hibernate caches when the
update actually changed something.

🤖 AI Assisted

* fix: Reload the object before diffing a non-owned collection

For a non-owned property such as OrganisationUnit.dataSets, the replace
diff reads the inverse collection, which is in the second-level cache
and is not evicted when only the owning side (DataSet.sources) changes:
on another cluster node, after an out-of-band change, or when a reader
caches it during a metadata import. A stale copy made a re-sent item
look unchanged, so the PUT returned 200 with nothing updated and the
link stayed missing.

Refresh the object first so the inverse collection is read from the
database. Evicting the cache entry alone is not enough, as the
collection is already loaded into the session by then. An unchanged PUT
now runs 3 statements instead of 1 (the object's row and its inverse
collection), still independent of the size of the owning collections.

🤖 AI Assisted
@jason-p-pickering
jason-p-pickering requested a review from jbee October 6, 2026 05:58
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

@jason-p-pickering
jason-p-pickering merged commit c273f9f into 2.43 Oct 7, 2026
18 checks passed
@jason-p-pickering
jason-p-pickering deleted the fix/DHIS2-22217-collection-replace-diff_2.43 branch October 7, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants