Skip to content

@Indexed secondary index keys are not expired when @RedisHash(timeToLive=…) entity expires #3255

@themohamedsabbah

Description

@themohamedsabbah

Description

When a Redis hash entity is annotated with @RedisHash(timeToLive = …) and includes fields marked with @indexed, Spring Data Redis correctly sets a TTL on the primary hash key (e.g., Session:123). Upon expiration, the primary hash is removed automatically.
However, the secondary index sets (e.g., Session:userId:456) are never assigned a TTL and remain in Redis indefinitely, even after the associated entity has expired.

Current Behavior

@RedisHash(timeToLive = 3600)
public class Session {
    @Id String id;
    @Indexed String userId;
}

Generated Redis commands (on save):

HSET Session:123 id "123" userId "456"
EXPIRE Session:123 3600
SADD Session:userId:456 "123"
# ← No EXPIRE on the index key!

After 1 hour:

  • Session:123 → deleted
  • Session:userId:456 → still exists (stale index entry)

Impact

  • Stale index data: Index points to non-existent entities.
  • Unbounded memory growth: For high-churn, short-lived entities (e.g., user sessions, auth tokens), index sets accumulate forever.
  • Operational burden: Requires manual cleanup or external expiration logic.

Proposed Solution
Extend @indexed with an optional flag:

@Indexed(expireWithEntity = boolean, default = false)

When expireWithEntity = true, Spring Data Redis should:

  • Apply the same TTL as the entity to each generated index set key upon save.
  • Optionally clean up empty index sets on expiration (if feasible).

Example:

@RedisHash(timeToLive = 3600)
public class Session {
    @Id private String id;

    @Indexed(expireWithEntity = true)
    private String userId;
}

Expected Redis commands:

HSET Session:123 ...
EXPIRE Session:123 3600
SADD Session:userId:456 "123"
EXPIRE Session:userId:456 3600   # ← Now expires with entity

Backward Compatibility

  • Default value: expireWithEntity = false
  • Existing applications unchanged
  • Opt-in only for use cases needing index TTL synchronization

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions