ISSUE #4793 - Clean up relationships on time series delete and skip orphaned incident rows#30156
ISSUE #4793 - Clean up relationships on time series delete and skip orphaned incident rows#30156TeddyCr wants to merge 5 commits into
Conversation
Code Review 👍 Approved with suggestions 2 resolved / 3 findingsHard deletion now cleans up relationships and search documents for all time-series entities, and the state-ID endpoint correctly skips orphaned rows to prevent 500 errors. Note that these changes to 💡 Quality: deleteById change affects all time-series subclasses, not just TCRSThe base-class deleteById now deletes relationships and invokes postDelete (search-doc removal) for every EntityTimeSeriesRepository subclass, including AgentExecutionResource and McpExecutionResource paths, not only testCaseResolutionStatus. Previously it only removed the row. This broadened behavior is likely desirable, but it is only exercised by the new TCRS integration test; verify the other time-series entities behave correctly (e.g. relationship cleanup and search deletion are safe/idempotent for them) or that deleteRelationships is overridden where different semantics are needed. ✅ 2 resolved✅ Bug: deleteById performs 3 DB writes without a transaction
✅ Bug: Duplicate existsById method breaks compilation
🤖 Prompt for agentsOptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
| for (CollectionDAO.EntityRelationshipRecord child : children) { | ||
| testCaseResolutionStatusRepository.deleteById(child.getId(), hardDelete); | ||
| } | ||
| TestCaseResolutionStatusRepository testCaseResolutionStatusRepository = |
There was a problem hiding this comment.
can this be async run, if there is 1 yr old test cse, we will have ton of data, this can take lot of time cleanup
Fixes
Fixes 4793-CLT
Problem
Viewing a test case at
data-quality/test-casestriggeredGET /dataQuality/testCases/testCaseIncidentStatus/stateId/{stateId}and returned a 500:A reindex made the error go away, which pointed at stale live-index state.
Root cause
Two independent defects, both on the
testCaseResolutionStatus(TCRS) delete path:EntityTimeSeriesRepository.deleteByIdnever cleaned up after itself. It deleted the time-series row but left theparentOfrelationship row behind and never calledpostDelete, so the search document survived too. Every hard delete of a test case leaked orphaned relationship rows and stale docs.The
stateIdendpoint had no tolerance for orphaned rows.TestCaseResolutionStatusRepository.listTestCaseResolutionStatusesForStateIdreads straight from the database and callssetInheritedFieldswithmustHaveRelationship = truefor every row. A single row whoseparentOfrelationship had gone missing failed the entire request with a 500 — even though the repository already had a guard for exactly this condition (shouldSkipSearchResultOnInheritedFieldError), wired only into the search-backed listing path.The user-visible chain: the test case search document names a
stateId, the UI requests it, and the DB still holds rows for thatstateIdwhose relationship is gone → 500.Changes
EntityTimeSeriesRepositorydeleteByIdnow deletes the entity's relationships and callspostDelete(removing the search doc) alongside the row. The record is loaded before the relationships are removed, becausesetInheritedFieldsresolves references through them.deleteRelationships(UUID)so subclasses can override the cleanup.TestCaseResolutionStatusRepositorylistTestCaseResolutionStatusesForStateIdnow skips orphaned rows instead of failing the whole request, reusing the existingshouldSkipSearchResultOnInheritedFieldErrorguard and logging a warning. Healthy rows are unaffected; non-matching exceptions still propagate.TestCaseRepositorydeleteChildrenthat deleted every child N times (the outer loop variable was only used for logging).Testing
New
openmetadata-integration-tests/.../StaleIncidentStatusIT.java(5 tests, real DB + ES via testcontainers):deleteByIdRemovesParentRelationshipstateIdEndpointSkipsOrphanedRowsstateIdEndpointReturnsHealthyIncidenttestCaseReferenceresolvedsoftDeleteLeavesRowAndRelationshipIntacthardDelete=falseis a no-opdeleteByIdIgnoresUnknownIdGreptile Summary
This PR cleans up stale incident-status data during test case deletion. The main changes are:
Confidence Score: 5/5
No additional blocking issue was identified in the updated code.
Important Files Changed
Comments Outside Diff (2)
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityTimeSeriesRepository.java, line 398 (link)Orphaned Rows Cannot Be Deleted
getById(id)resolves inherited fields before returning. For an existing resolution-status row whoseparentOfrelationship is already missing, that lookup throws before cleanup begins, so the hard-delete path cannot remove the exact legacy orphan this change is meant to handle.Context Used: CLAUDE.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityTimeSeriesRepository.java, line 400-402 (link)Delete Steps Can Partially Commit
The relationship deletion, row deletion, and search cleanup are separate operations without a transaction covering this method. If the row deletion fails after
deleteRelationships, the row and search document survive without their relationships; ifpostDeletefails, the database row is gone while its search document remains.Context Used: CLAUDE.md (source)
Reviews (3): Last reviewed commit: "fix: clean duplicate method" | Re-trigger Greptile
Context used: