Conversation
|
I could not fully reproduce the exact Druid/PostgreSQL environment from #3505 in this branch, but I was able to deterministically reproduce the MyBatis core problem in tests.
This patch changes |
|
I still could not fully reproduce the exact Druid + PostgreSQL environment from issue #3505, so I do not want to overclaim that part. However, I was able to deterministically reproduce the MyBatis core problem covered by this PR. I verified the behavior in two states: base commit without the fix: fca05b7 mvn -Denforcer.skip=true -Dlicense.skip=true -Dformatter.skip=true -Dimpsort.skip=true -Drewrite.skip=true -Dgit-build-hook.skip=true -Dwhitespace.skip=true -Dtest=org.apache.ibatis.executor.ReuseExecutorTest test the new regression tests fail on the unfixed base and pass on the PR head. On the unfixed base, the failures are: shouldNotReuseClosedStatement() So the before/after behavior is: before the fix: a closed cached statement can still be considered reusable |
Summary
ReuseExecutorWhy
ReuseExecutorcurrently treats a cached statement as reusable when the connection is still open, but it does not check whether the statement itself has already been closed. In cursor scenarios, the driver or pool may close a statement independently while keeping the connection alive, leaving a stale entry instatementMap.Once that happens, MyBatis may try to parameterize and execute a closed statement on the next reuse attempt. This change makes
ReuseExecutortreat closed statements as non-reusable and prepare a fresh statement instead.Closes #3505