I'm using a CrudRepository
for connecting to Redis in my Spring Boot application and a @TimeToLive
annotated field in the entity for expiration:
@RedisHash("keyspace")public class MyRedisEntity { @Id String key; MyPojo pojo; @TimeToLive Long ttl;}public interface MyRedisRepository extends CrudRepository<MyRedisEntity, String>{}
Now when the expiration has taken place, myRedisRepo.findAll()
returns null for the expired entities. I discovered redis (or spring-data redis) stores all inserted entities' id in a set with the keyspace as key:
redis-cli> smembers keyspace0) key01) key12) key2...redis-cli> hgetall key0(empty list or set)
I suspect this set is used for the findAll
call, returning null for ids no longer present as hashmaps due to expiration. Also, I tried using a listener for RedisKeyExpiredEvent
, using the repository's delete method in onApplicationEvent
, but that doesn't help.
@Componentpublic 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())); } }}
What should I do to get only non null entries? Ideally I'd want the expired entries to be deleted entirely from redis and thus not appear in findAll
, but it'd be sufficient if a repository method could return list of non null values.
(And yes, I know about the phantom behaviour, but I don't think it's relevant to what I want)