PwDevWorks
PwDevWorks

Reputation: 41

How can we configure TTL for RedisHash using SpringBoot?

I am trying to configure TTL on RedisHash. I want to set same expiry to all the keys.

1st: I tried by adding annotation @RedisHash(value="MyHash",timeToLive=60) on the entity class.

2nd: Add a new field as expiration with @TimetoLive along with @RedisHash(value="MyHash",timeToLive=60)

@RedisHash(value = "MyHash", timeToLive = 60L)
public class MyHash {
.../attributes with few indexes
     @TimeToLive
    private Long expiration;
}

3rd: Added @EnableRedisRepositories with KeyspaceConfiguration

@EnableRedisRepositories(basePackageClasses = MyHash.class, keyspaceConfiguration = MyKeyspaceConfiguration.class)
public class RedisConfig {
//LettuceConnectionFactory
//RedisTemplate
}

public class MyKeyspaceConfiguration extends KeyspaceConfiguration {
    @Override
    public boolean hasSettingsFor(Class<?> type) {
        return true;
    }

    @Override
    public KeyspaceSettings getKeyspaceSettings(Class<?> type) {

        KeyspaceSettings keyspaceSettings = new KeyspaceSettings(MyHash.class, "MyHashlog");
        keyspaceSettings.setTimeToLive(60L);

        return keyspaceSettings;
    }
}

My Repository:

public interface MyHashRepository extends CrudRepository<MyHash, Long> {

    List<MyHash> findByApplicationId(String applicationId) ;
}

All above approach do not set any expiry. When I check in Redis it shows -1.

TTL MyHash:applicationId:e1hd9-w6q0s-5jd3e-wi2h4
(integer) -1

Upvotes: 2

Views: 9950

Answers (2)

Jennifer Kron
Jennifer Kron

Reputation: 19

I was able to solve this two ways:

Solution 1: Adding the @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) to my configuration class

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3000)
open class RedisConfig{}

Solution 2: Extending the RedisHttpSessionConfiguration class and calling setMaxInactiveIntervalInSeconds

@Configuration
open class RedisConfig: RedisHttpSessionConfiguration() {

    @PostConstruct
    open fun afterPropertiesSet() {
        val ttlInSeconds = 3000
        this.setMaxInactiveIntervalInSeconds(ttlInSeconds)
    }

I opted for the latter so that I can eventually add the ttl as a config value.

Upvotes: 0

PwDevWorks
PwDevWorks

Reputation: 41

Found the solution: We need to add enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP attribute as below,

Solution 1: Using @RedisHash to set TTL

//Add annotation on config or Spring boot main class
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
@SpringBootApplication
public class RedisLogServiceApplication implements WebMvcConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(RedisLogServiceApplication.class, args);
    }
}

@RedisHash(value = "MyHash", timeToLive = 60L)
public class MyHash {
.../attributes with few indexes
    @Id
    private Long id;
    @Indexed
    private String applicationId;
}

Solution 2: Use KeySapceConfiguration for setting TTL

//Add annotation on config or Spring boot main class
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP, keyspaceConfiguration = MyKeyspaceConfiguration.class)
@SpringBootApplication
public class RedisLogServiceApplication implements WebMvcConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(RedisLogServiceApplication.class, args);
    }
}

//MyKeyspaceConfiguration.class to set TTL
public class MyKeyspaceConfiguration extends KeyspaceConfiguration {
    @Override
    public boolean hasSettingsFor(Class<?> type) {
        return true;
    }

    @Override
    public KeyspaceSettings getKeyspaceSettings(Class<?> type) {

        KeyspaceSettings keyspaceSettings = new KeyspaceSettings(MyHash.class, "MyHashlog");
        keyspaceSettings.setTimeToLive(60L);

        return keyspaceSettings;
    }
}

@RedisHash(value = "MyHash")
public class MyHash {
.../attributes with few indexes
    @Id
    private Long id;
    @Indexed
    private String applicationId;
}

No changes to Repository:

public interface MyHashRepository extends CrudRepository<MyHash, Long> {

    List<MyHash> findByApplicationId(String applicationId) ;
}

Also Spring will create multiple keys based on the attributes that are annotated as @Indexed in your entity class. However, TTL is only applied on the primary key i.e. @Id. For example, When I run keys command in redis-cli

>keys MyHash*
1) MyHash:id:e1hd9-w6q0s-5jd3e-wi2h4
2) MyHash:applicationId:e1hd9-w6q0s-5jd3e-wi2h4

>TTL MyHash:id:e1hd9-w6q0s-5jd3e-wi2h4
(integer) 59
>TTL MyHash:applicationId:e1hd9-w6q0s-5jd3e-wi2h4
(integer) -1

//After Expiry:
>keys MyHash*
(no keys)
>TTL MyHash:id:e1hd9-w6q0s-5jd3e-wi2h4
(integer) -2

Upvotes: 2

Related Questions