Conversation
…epository Two independent papercuts in the same area. CachedEntityDao.invalidateByName and deleteByName each issued two DELs, one per alias. Between them a concurrent reader can see one alias evicted and the other still live, and cache a view of the entity assembled from both halves. CacheProvider.del is already varargs, so this is one call. SearchSettingsMergeUtil resolved Entity.getSystemRepository() into a static final field. SystemRepository's constructor ends with Entity.setSystemRepository(this) and callers construct one freely - OpenMetadataApplication, OpenMetadataOperations, the @repository scan, and EmailUtil on every use - so the global is replaced repeatedly while the field pins whichever instance was current when this migration utility first loaded. The instances are equivalent while they share a CollectionDAO, so this is a latent hazard rather than a live failure, but it is a service-locator call frozen at class-init with a silent failure mode. Both tests fail on main: the eviction tests report 2 dels where 1 is expected, and the merge-util test reads back the stale repository's settings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
✅ PR checks passedThe linked issue has a description and all required Shipping project fields set. Thanks! |
✅ Playwright Results — workflow succeededValidated commit ✅ 4471 passed · ❌ 0 failed · 🟡 10 flaky · ⏭️ 1 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 1h 2m 32s ⏱️ Max setup 4m 27s · max shard execution 22m 23s · max shard-job elapsed before upload 25m 30s · reporting 18s 🌐 219.67 requests/attempt · 2.23 app boots/UI scenario · 36.41% common-shard skew Optimization targets still in progress:
🟡 10 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
Code Review ✅ ApprovedConsolidates name-alias cache eviction into a single Redis deletion and resolves OptionsDisplay: compact → Counting what did not apply, without listing it. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
Describe your changes:
Fixes #33538. Salvaged from the closed PR #33248 (tracking: #33528).
Two independent papercuts in the same area.
1. A name-keyed cache entry is evicted with two round trips.
CachedEntityDao.invalidateByNameand
deleteByNameeach issued twoDELs — one for the entity alias, one for the reference alias.Between them a concurrent reader can see one alias evicted and the other still live, and cache a view
of the entity assembled from both halves.
CacheProvider.delis alreadydel(String... keys), sothis is one call.
2.
SearchSettingsMergeUtilpinnedSystemRepositoryat class-load time.SystemRepository's constructor ends withEntity.setSystemRepository(this), and callers constructone freely —
OpenMetadataApplication:315,OpenMetadataOperations:3416, the@Repositoryscan inEntity.initializeRepositories, andEmailUtil:440on every use. So the global is replacedrepeatedly over a JVM's life while this field keeps whichever instance was current when the class
first loaded — and it is a migration utility, loaded at whatever point the first migration touches it.
On severity, honestly: the instances are functionally equivalent as long as they share the same
CollectionDAO, so this is a latent correctness hazard rather than a reproducible productionfailure. It is worth fixing because it is a service-locator call frozen at class-init, the failure
mode is silent, and any change to bootstrap ordering turns it into an NPE for the life of the
process. It is a concrete instance of #33523.
I deliberately did not take the branch's other edits to these two files: its
EntityRepository.class→EntityPolicy.classclassloader swap does not apply tomain, and therest is an automated comment reflow.
Type of change:
High-level design:
N/A — two small, independent changes. 6 production lines net.
Tests:
Use cases covered
SystemRepositorythat is registerednow, not the one that was registered when the utility class happened to load.
Unit tests
Four new tests, all of which fail on
main:CachedEntityDaoAliasEvictionTest(a recordingCacheProvideroverNoopCacheProvider— no mocksof our own classes):
invalidateByNameEvictsBothAliasesInOneCall— onmain:expected: <1> but was: <2>deleteByNameEvictsBothAliasesInOneCall— onmain:expected: <1> but was: <2>invalidateByIdStillEvictsTheSingleKeyItOwns— guards against over-collapsingSearchSettingsMergeUtilTest(@Isolated, swaps the registered repository):searchSettingsResolveTheCurrentlyRegisteredSystemRepository— onmainit reads back the stalerepository's
SettingssavingSettingsWritesThroughToTheCurrentlyRegisteredSystemRepositoryAfter the change, 34 tests green across the new classes plus every pre-existing test in
service/cache(EntityCacheBypassTest,ListCountCacheTest,BundleWarmupBatcherTest,RedisCacheProviderStateMachineTest).Backend integration tests
Not applicable — no API change.
Ingestion integration tests
Not applicable.
Playwright (UI) tests
Not applicable — no UI change.
Manual testing performed
mvn -pl openmetadata-service test -Dtest='SearchSettingsMergeUtilTest,CachedEntityDaoAliasEvictionTest,...'— 34 tests, BUILD SUCCESS.origin/main— 4 failures, exactly the 4 new tests, with the messages quoted above.mvn spotless:apply -pl openmetadata-service— clean.UI screen recording / screenshots:
Not applicable.
Checklist:
Fixes <issue-number>: <short explanation>Fixes #33538.🤖 Generated with Claude Code
The PR appears safe to merge; no actionable correctness, security, or repository-rule violations remain.
Summary
This PR fixes two lifecycle and consistency hazards in service-layer utilities:
SystemRepositoryat each search-settings read and write instead of retaining a class-load-time instance.Reviews (3) · Last reviewed commit: "Merge branch 'main' into harshach/fix-st..."