SpringBoot中@Cacheable注解不生效问题求助
数据库查询缓存失效问题排查与解决
问题描述
我编写了一段理论上应缓存查询表数据的Java代码,编译正常且程序可运行,但数据集并未被缓存,每次调用方法时都会执行数据库查询。请问如何实现数据库查询一次后缓存数据,后续调用直接使用缓存?
代码示例
@Cacheable(value = "eventTypes", key = "#p0") public List<EventType> getEventTypes() { String sql = "select * from event_types "; return jdbcTemplate.query(sql, new Object[] {}, (rs, rowNum) -> EventType.builder() .eventTypeId(rs.getLong("event_type_id")) .description(rs.getString("description")) .build() ); }
配置文件(application.properties)
cache: cache-names:eventTypes,users
问题排查与解决步骤
- 修正@Cacheable的key配置:你的
getEventTypes方法没有参数,#p0代表第一个方法参数,这里不存在该参数会导致key生成异常。可以直接移除key属性(Spring会根据方法签名默认生成key),或者指定固定key:@Cacheable(value = "eventTypes", key = "'eventTypes'")。 - 启用Spring缓存功能:必须在Spring Boot主启动类上添加
@EnableCaching注解,否则所有缓存注解都不会生效,这是缓存功能生效的核心前提。 - 修正配置文件前缀:Spring Boot的缓存配置前缀是
spring.cache,你的配置缺少前缀导致不生效,应修改为:spring.cache.cache-names=eventTypes,users - 避免内部方法调用:如果是在同一个类内部直接调用
getEventTypes方法,Spring的AOP代理不会触发缓存逻辑。需要通过注入当前类的Bean实例来调用方法,或者将缓存方法抽取到独立的Service类中。 - 确保缓存对象可序列化:如果使用的缓存实现(如Redis)需要序列化对象,
EventType类需要实现Serializable接口,否则无法正常存储缓存数据。
内容的提问来源于stack exchange,提问作者Walker Farrow
相关产品推荐
相关产品推荐

