【发布时间】:2019-12-25 15:36:22
【问题描述】:
我在我的 Spring Boot 应用程序中使用CrudRepository 连接到 Redis,并在实体中使用 @TimeToLive 注释字段来过期:
@RedisHash("keyspace")
public class MyRedisEntity {
@Id String key;
MyPojo pojo;
@TimeToLive Long ttl;
}
public interface MyRedisRepository extends CrudRepository<MyRedisEntity, String>{}
现在,当到期时,myRedisRepo.findAll() 为已到期的实体返回 null。我发现 redis(或 spring-data redis)将所有插入的实体的 id 存储在一个集合中,其中键空间作为键:
redis-cli> smembers keyspace
0) key0
1) key1
2) key2
...
redis-cli> hgetall key0
(empty list or set)
我怀疑这个集合用于findAll 调用,返回 null 以表示由于过期而不再作为哈希映射存在的 id。另外,我尝试使用RedisKeyExpiredEvent 的侦听器,使用onApplicationEvent 中存储库的删除方法,但这无济于事。
@Component
public class RedisExpirationListener implements ApplicationListener<RedisKeyExpiredEvent> {
private MyRedisRepository myRedisRepository;
@Autowired
public RedisExpirationListener(MyRedisRepository myRedisRepository) {
this.myRedisRepository = myRedisRepository;
}
@Override
public void onApplicationEvent(RedisKeyExpiredEvent redisKeyExpiredEvent) {
if (redisKeyExpiredEvent.getKeyspace().equals("keyspace")) {
myRedisRepository.deleteById(new String(redisKeyExpiredEvent.getId()));
}
}
}
我应该怎么做才能只获得非空条目?理想情况下,我希望将过期条目从 redis 中完全删除,因此不会出现在findAll 中,但如果存储库方法可以返回非空值列表就足够了。
(是的,我知道幻影行为,但我认为它与我想要的无关)
【问题讨论】:
-
嗨@aksh1618,你能在哪里解决这个问题?你的解决方法是什么?看到这个jira.spring.io/browse/DATAREDIS-570 但还没有修复
-
@Enoobong 我不得不在我使用过的所有地方进行过滤
findAll:StreamSupport.stream(myRedisRepository.findAll().spliterator(), false).filter(Objects::nonNull) -
好的,谢谢,我也是????
标签: java spring redis spring-data