@Cacheable кэширует null — и это остаётся навсегда

Вопрос проверяет, понимаете ли вы, что кэш в Spring по умолчанию не отличает «данных пока нет» от «результат — null». ConcurrentMapCache и большинство реализаций хранят null как обычное значение, оборачивая его в служебный объект.

Если метод один раз вернул null — например, запись в БД ещё не успела появиться — кэш запомнит именно null. Все следующие вызовы будут получать null из кэша, даже когда запись в БД уже есть, до истечения TTL или явной инвалидации.

@Cacheable( value = "user", unless = "#result == null" ) public User findUser(Long id) { return repository .findById(id) .orElse(null); }

Следующий вопрос обычно про разницу между этим и багом в БД: как отличить «кэш отдаёт протухшие null» от «данных реально нет». Ещё спросят про @CacheEvict на методе создания записи — это надёжнее, чем ждать TTL.

Финал: unless — не опция для перфекционистов, а способ не кэшировать отсутствие данных как факт.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки