#3768·mybatis-3

FifoCache evicts an unrelated entry when an existing key is re-put

Author: harrisleeshCreated Sep 3, 2026Updated Sep 16, 2026

MyBatis version

master (c5e06b1), also present in 3.5.x

Description

FifoCache.cycleKeyList appends the key to the internal Deque on every putObject, without checking whether the key is already tracked. Re-putting an existing key (a normal cache refresh) therefore adds a duplicate entry to the key list while the delegate cache size stays the same. Once the list exceeds size, the cache evicts the oldest key — even though the actual number of cached entries never exceeded the limit — and after several refreshes of the same key, a single eviction pass can remove an entry while duplicates of the refreshed key still occupy list slots, shrinking the effective capacity.

Steps to reproduce

java
FifoCache cache = new FifoCache(new PerpetualCache("default"));
cache.setSize(2);
cache.putObject(0, 0);
cache.putObject(1, 1);
cache.putObject(0, 0); // refresh existing key
assertNotNull(cache.getObject(1)); // fails: key 1 was evicted, only 2 distinct keys exist

Expected result

Re-putting an existing key must not evict another entry; eviction should occur only when the number of distinct cached keys exceeds the configured size. Replacing the Deque with a LinkedHashSet preserves FIFO order by first insertion and fixes this. I will submit a PR with a failing test and fix.