@Cacheable: сначала определить пакет

В Java-приложении встречаются две разные аннотации с одинаковым коротким именем.

Полное имяЧто кэшируется
jakarta.persistence.Cacheableэкземпляры JPA-сущности во втором уровне кэша provider-а
org.springframework.cache.annotation.Cacheableрезультат вызова Spring-метода

JPA second-level cache

@Entity
@jakarta.persistence.Cacheable(true)
class Country {
    @Id
    private String code;
 
    private String name;
 
    protected Country() {
        // нужен JPA provider-у
    }
}

Аннотация только сообщает о допустимости кэширования. Нужны включённый L2 cache, выбранный provider и регион/стратегия. First-level cache принадлежит EntityManager и существует всегда; second-level разделяется между сессиями.

Кэш сущности не обязательно кэширует произвольные запросы и коллекции связей. Для Hibernate стратегия конкурентного доступа задаётся отдельно. Неподходящая стратегия или внешнее изменение БД дают устаревшие данные.

Spring Cache

@org.springframework.cache.annotation.Cacheable(
        cacheNames = "countryByCode",
        key = "#code",
        unless = "#result == null"
)
public CountryView findCountry(String code) {
    return repository.findViewByCode(code);
}

Spring обычно перехватывает вызов через proxy: строит ключ, ищет значение, при промахе вызывает метод и сохраняет результат. Самовызов метода внутри того же объекта часто проходит мимо proxy. Для обновлений нужны согласованные @CachePut/@CacheEvict или другой план инвалидции.

Когда кэш вреден

  • данные меняются чаще, чем читаются;
  • нет допустимого времени устаревания;
  • ключ не включает все влияющие аргументы, пользователя или локаль;
  • в кэш попадают управляемые изменяемые entity;
  • несколько узлов не согласуют инвалидцию.

На собеседовании

Включает ли JPA @Cacheable second-level cache сама? Нет, это часть конфигурации provider-а.

Совпадает ли L2 cache с кэшем запросов? Нет.

Почему Spring @Cacheable может не сработать при this.find()? Вызов не пересёк proxy.

Что сложнее записи в кэш? Корректная инвалидция и модель допустимой устарелости.

Связано: Кэширование hibernate, Spring AOP, Spring Data JPA.