orElse с обращением в базу: когда выполнится дорогой вызов
В сервисе профилей сделали кэш поверх репозитория:
public User getUser(Long id) {
Optional<User> cached = cache.find(id);
return cached.orElse(repository.loadById(id));
}
На код-ревью замечают, что нагрузка на базу не снизилась после внедрения кэша. Почему?
- Аргумент orElse вычисляется всегда, ещё до входа в метод: нужен orElseGet с ленивой лямбдой
- Optional кэширует пустое значение внутри себя, поэтому cache.find после первого промаха всегда возвращает empty
- orElse обращается к базе только при промахе кэша, значит дело в самом кэше: он не сохраняет найденные значения
- Нужно заменить orElse на orElseThrow и ловить исключение — тогда лишний запрос в базу выполняться не будет
