Skip to content

perf: replace /dataEntry/metadata with flat per-type requests [DHIS2-…#577

Open
stian-sandvold wants to merge 1 commit into
dhis2:claude-data-fetch-rewritefrom
stian-sandvold:DHIS2-21757-flat-metadata-fetch
Open

perf: replace /dataEntry/metadata with flat per-type requests [DHIS2-…#577
stian-sandvold wants to merge 1 commit into
dhis2:claude-data-fetch-rewritefrom
stian-sandvold:DHIS2-21757-flat-metadata-fetch

Conversation

@stian-sandvold

Copy link
Copy Markdown

The bespoke GET /api/dataEntry/metadata endpoint walks the whole metadata entity graph via lazy Hibernate associations, causing an N+1 query explosion (10,202 SQL statements / 245s / HTTP 500 on the Uganda instance). Its cost scales with the size of the user's writable metadata.

Rebuild the same metadata client-side from flat, bulk, per-type requests to the standard metadata endpoints instead. useMetadata()'s return shape is unchanged (id-keyed dicts via hashArraysInObject), so every selector and consumer is untouched. Verified byte-equivalent against the real endpoint on the Sierra Leone demo (757 entities across 7 types match exactly), and ~6-8x fewer SQL statements (~230-300 vs ~1,880), well-batched per type.

Also marks the query meta.persist so the preloaded metadata survives reloads and is available offline (the endpoint's original purpose).

…21757]

The bespoke GET /api/dataEntry/metadata endpoint walks the whole metadata
entity graph via lazy Hibernate associations, causing an N+1 query explosion
(10,202 SQL statements / 245s / HTTP 500 on the Uganda instance). Its cost
scales with the size of the user's writable metadata.

Rebuild the same metadata client-side from flat, bulk, per-type requests to the
standard metadata endpoints instead. useMetadata()'s return shape is unchanged
(id-keyed dicts via hashArraysInObject), so every selector and consumer is
untouched. Verified byte-equivalent against the real endpoint on the Sierra
Leone demo (757 entities across 7 types match exactly), and ~6-8x fewer SQL
statements (~230-300 vs ~1,880), well-batched per type.

Also marks the query meta.persist so the preloaded metadata survives reloads
and is available offline (the endpoint's original purpose).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant