Skip to content

Commit 0446ae5

Browse files
jr-rkmilanmajchrakclaude
authored
TUL/fix: prevent orphaned items - abort leaked request Context (backport #1352 to tul) (#1354)
* fix: abort leaked request Context in StatelessAuthenticationFilter (backport dc57ffd / #852) Backport the behavioral fix from dc57ffd ("Transaction bug - close context in finally block", PR #852) which is on dtq-dev/customer/lindat but missing from customer/zcu-data. On the request error path a slow submission upload could leave its Hibernate session bound to the Tomcat thread with a dirty, stale Item: the upload throws before reaching context.commit(), and DSpaceRequestContextFilter assigns its `context` local only AFTER chain.doFilter, so on an exception the local stays null and its finally skips the abort -> the session leaks. A later request on that thread then flushes the stale Item as a full-row UPDATE (Item has no @DynamicUpdate/@Version), reverting owning_collection->NULL and in_archive->false while collection2item + handle survive -> the item becomes an unsearchable orphan (e.g. handle 20.500.14592/107). Wrap chain.doFilter in the outer StatelessAuthenticationFilter with a try/finally that reads the Context from the request attribute and abort()s it if still valid, cleaning up the leaked context the inner filter missed. No-op on the normal success path. Only the StatelessAuthenticationFilter hunk is ported; the diagnostic/CI files in dc57ffd are omitted (they conflict and are not needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> (cherry picked from commit ea6116e) * docs: clarify Context-abort comment and link #1353 (Copilot review) --------- Co-authored-by: milanmajchrak <milan.majchrak@dataquest.sk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ccdbf8f commit 0446ae5

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

dspace-server-webapp/src/main/java/org/dspace/app/rest/security/StatelessAuthenticationFilter.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,23 @@ protected void doFilterInternal(HttpServletRequest req,
9999
if (authentication != null) {
100100
SecurityContextHolder.getContext().setAuthentication(authentication);
101101
}
102-
chain.doFilter(req, res);
102+
103+
try {
104+
chain.doFilter(req, res);
105+
} finally {
106+
// Abort the request-scoped DSpace Context if it is still open, so a leaked, dirty
107+
// Hibernate session is not left bound to the worker thread (prevents orphaned items).
108+
// See https://github.com/dataquest-dev/DSpace/issues/1353
109+
Context context = (Context) req.getAttribute(ContextUtil.DSPACE_CONTEXT);
110+
// Ensure the context is cleared after the request is done
111+
if (context != null && context.isValid()) {
112+
try {
113+
context.abort();
114+
} catch (Exception e) {
115+
log.error("{} occurred while trying to close", e.getMessage(), e);
116+
}
117+
}
118+
}
103119
}
104120

105121
/**

0 commit comments

Comments
 (0)