You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Spring Data Redis时抛出NoSuchElementException: No value present如何解决

异常原因

java.util.NoSuchElementException: No value present 异常的直接触发逻辑是CrudRepository.findById()方法返回Optional类型容器,当容器内不存在查询结果时直接调用get()方法就会抛出该异常。你的场景中具体触发原因包含以下几点:

  • 查询ID不存在:测试代码直接使用UUID.randomUUID().toString()作为查询ID,随机生成的ID默认在Redis中没有对应缓存数据,必然返回空的Optional容器。
  • Repository泛型配置错误:你定义的Repository继承CrudRepository<repoRedisEntity, String>,但实际实体类名为RedisEntity,泛型类型不匹配会导致结果映射失败,查询不到数据。
  • RedisTemplate序列化规则缺失:当前RedisTemplate未配置key、value的序列化规则,默认使用JDK序列化机制,会导致存储的key和你查询的字符串ID格式不匹配,即使Redis中存在对应数据也会查询为空。
  • 代码笔误:测试代码中将查询结果赋值给retrievedEntity变量,后续操作却使用了未定义的retrievedQuoteRedisEntity变量,会导致编译或运行错误。
可行解决方案
  • 保证查询ID对应的数据已存在
    先构造实体对象存入Redis,再用存入的ID进行查询,示例代码如下:
    // 先写入数据
    String targetId = UUID.randomUUID().toString();
    RedisEntity initEntity = new RedisEntity(targetId, 0.0);
    quoteRedisRepository.save(initEntity);
    // 再执行查询
    RedisEntity retrievedEntity = quoteRedisRepository.findById(targetId).get();
    
  • 对Optional结果做空判断,避免直接调用get()
    优先使用isPresent()判空,或使用orElse()/orElseGet()/orElseThrow()等方法处理空结果场景,示例代码如下:
    Optional<RedisEntity> entityOptional = quoteRedisRepository.findById(targetId);
    if (entityOptional.isPresent()) {
        RedisEntity retrievedEntity = entityOptional.get();
        retrievedEntity.setPrice(10 * item / 100);
        quoteRedisRepository.save(retrievedEntity);
    } else {
        // 处理数据不存在的逻辑,例如新建对象存入
        RedisEntity newEntity = new RedisEntity(targetId, 10 * item / 100);
        quoteRedisRepository.save(newEntity);
    }
    
  • 修正Repository泛型配置
    将Repository的泛型类型替换为实际的实体类:
    @Repository
    public interface QuoteRedisRepository extends CrudRepository<RedisEntity, String> {
    }
    
  • 完善RedisTemplate序列化配置
    给RedisTemplate设置适配的序列化规则,避免序列化不匹配导致的查询失败:
    @Bean
    RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        // key使用String序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // value使用JSON序列化
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(jsonSerializer);
        redisTemplate.setHashValueSerializer(jsonSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    
  • 修正测试代码中的变量名笔误,保证变量名前后一致。

内容的提问来源于stack exchange,提问作者user1167642

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:27:04