EntityManager leak in ThreadLocal when connection is lost during transaction
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 1.7k
- Avg merge
- 11m
- Merged PRs (30d)
- 2
Description
## Summary
When using guice-persist with a web server such as Jetty, a broken EntityManager may leak into subsequent requests due to flawed cleanup logic in the transaction interceptor.
## Bug description
- A request is handled by a Jetty thread.
- Guice interceptor opens a database connection and stores the EntityManager in a ThreadLocal.
- A network blip occurs, breaking the database connection mid-transaction.
- On commit/rollback, an exception is thrown.
- The interceptor cleanup logic checks if (transaction.isActive()).
- Because the connection is already dead, this returns false.
- As a result, the cleanup logic skips removal of the EntityManager from the ThreadLocal.
- The thread is reused by Jetty for a new request.
- The broken EntityManager is still present in the ThreadLocal.
- The new request fails immediately.
## Expected Behavior
If the connection is no longer open, the EntityManager should be removed from the ThreadLocal during cleanup.
## Actual Behavior
If the transaction is no longer "active" (e.g., due to connection loss), cleanup is skipped and the broken EntityManager persists in the ThreadLocal, poisoning subsequent requests.
## Impact
- Causes intermittent request failures.
- Leads to hard-to-debug production issues when connections are lost.
- Especially problematic in long-lived thread pools like Jetty, Tomcat, or Netty.
## Similar issue
https://github.com/google/guice/issues/1179
## Proposed Fix
Remove the EntityManager from the thread’s ThreadLocal in the cleanup logic if the connection is no longer open
## Contribution
I plan to open a PR with a fix for this issue shortly. Feedback on the proposed approach is welcome before I finalize the patch.
Contributor guide
Assessment
This issue has not been assessed yet.