skip to content

RedisTemplate & Redis Repositories

RedisTemplate exposes the Redis data structures directly and lets you choose serializers, while @RedisHash entities give you repository-style access with secondary indexes. Serializer choice is the detail that gets asked, because it decides whether other clients can read your data.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is RedisTemplate (and StringRedisTemplate) in Spring Data Redis, and how do you read/write a value with it?

level: juniorimportance: must knowfreq 70%

answer

  1. opsForValue/Hash/List = pick the structure first
  2. StringRedisTemplate = String keys+values, readable in redis-cli
  3. plain RedisTemplate default = JDK binary serializer
  4. backed by RedisConnectionFactory (Lettuce)
  5. Boot auto-configures both beans

basics

~10 s

RedisTemplate is Spring's helper class for talking to Redis. You get an operations object like opsForValue() and call set/get. StringRedisTemplate is a ready-made version where keys and values are Strings.

solid answer

~30 s

RedisTemplate<K,V> is the central Spring abstraction over a Redis connection (via a RedisConnectionFactory like Lettuce). Instead of raw commands you use typed operation bundles: opsForValue() (single values/GET/SET), opsForHash() (field-value maps), opsForList(), opsForSet(), opsForZSet(). StringRedisTemplate is a subclass pre-wired with StringRedisSerializer for keys and values, ideal when everything is text and you want human-readable keys in redis-cli. Plain RedisTemplate defaults to JdkSerializationRedisSerializer, producing opaque binary blobs. Spring Boot auto-configures both beans when spring-boot-starter-data-redis is present, so you just inject them. Example: stringRedisTemplate.opsForValue().set("user:1:name", "Ann"); String n = stringRedisTemplate.opsForValue().get("user:1:name");

code

java · 21 lines
java
@Service
public class SessionCache {
    private final StringRedisTemplate redis;

    public SessionCache(StringRedisTemplate redis) {
        this.redis = redis;
    }

    public void put(String sessionId, String userId) {
        // SET session:<id> <userId> EX 1800
        redis.opsForValue().set("session:" + sessionId, userId, Duration.ofMinutes(30));
    }

    public String lookup(String sessionId) {
        return redis.opsForValue().get("session:" + sessionId);
    }

    public long incrementHits(String userId) {
        return redis.opsForValue().increment("hits:" + userId); // INCR
    }
}

go deeper

for a junior

Should know opsForValue set/get and that StringRedisTemplate is for text keys/values.

for a middle

Should name the other operation bundles and the default-serializer gotcha.

for a senior

Should explain the connection factory layer, boundOps, and when to reach for the template vs repositories.

for a principal

Should discuss serializer choice for interop/observability and standardizing a template configuration across services.

**Redis** is an in-memory key-value data store often used for caching, sessions, counters, and ephemeral data. **Spring Data Redis** is the Spring module that lets your Java/Kotlin app talk to Redis without writing raw protocol commands. **RedisConnectionFactory** — the lowest-level piece. It produces connections to the Redis server. Two implementations exist: **LettuceConnectionFactory** (default in Spring Boot, Netty-based, thread-safe) and **JedisConnectionFactory**. You normally never touch this directly; Spring Boot auto-configures it from `spring.data.redis.host`/`port` properties. **RedisTemplate<K, V>** — the main class you use. It wraps a connection factory and exposes high-level, thread-safe operations. The generics are the key type and value type. Because Redis stores raw bytes, RedisTemplate uses **serializers** to convert your K/V objects to/from `byte[]`. **Operation bundles** — you never call Redis commands directly on the template; you first pick a data-structure-specific bundle: - `opsForValue()` → `ValueOperations` — simple string/value ops: `set`, `get`, `increment`, `setIfAbsent` (SETNX). - `opsForHash()` → `HashOperations` — Redis hashes (a map stored under one key): `put`, `get`, `entries`, `delete`. - `opsForList()` → `ListOperations` — `leftPush`, `rightPush`, `range`, good for queues. - `opsForSet()` / `opsForZSet()` — unordered sets and sorted sets. There are also `boundValueOps(key)` etc. that bind a key once so you don't repeat it. **StringRedisTemplate** — a convenience subclass of `RedisTemplate<String, String>` pre-configured with `StringRedisSerializer` for keys, values, hash keys, and hash values. Use it when all your data is text. Its big advantage: keys and values look normal in `redis-cli` (e.g. `GET user:1:name` returns `Ann`), which makes debugging far easier than the binary blobs plain RedisTemplate produces by default. **Auto-configuration** — adding `spring-boot-starter-data-redis` makes Spring Boot create both a `RedisTemplate<Object,Object>` and a `StringRedisTemplate` bean automatically, plus the connection factory. You just `@Autowired`/inject them. **Default serializer gotcha** — plain `RedisTemplate` defaults to `JdkSerializationRedisSerializer`. That means values are Java-serialized binary — unreadable in redis-cli, tied to the exact Java class, and not interoperable with non-Java clients. This is the single most common surprise; people expect readable JSON and get `\xac\xed...`. Fix by setting explicit serializers (covered in the serializer question). **When to use RedisTemplate vs. repositories** — RedisTemplate is the imperative, command-level tool: caching, counters, distributed locks, pub/sub, custom data structures. `@RedisHash` repositories (a separate feature) give you a JPA-like `CrudRepository` over object entities. Use the template when you want fine control over the actual Redis data structure. **Thread-safety** — RedisTemplate and StringRedisTemplate are thread-safe once configured; share a single bean across the app.

  • Why might GET in redis-cli show garbage bytes when you used a plain RedisTemplate?
    Because plain RedisTemplate defaults to JdkSerializationRedisSerializer, which Java-serializes values into binary. Use StringRedisTemplate or set a StringRedisSerializer/JSON serializer to get readable output.
  • What does opsForValue().increment() require of the stored value?
    The value must be a valid integer/long encoded as a string; INCR fails on non-numeric values. StringRedisTemplate stores '5' as text and Redis parses it for INCR.

saying these in an interview costs you the question

  • Thinking RedisTemplate stores JSON by default (it uses JDK binary serialization)
  • Believing you call Redis commands directly on the template instead of via opsForXxx()
  • Confusing StringRedisTemplate with a different connection type rather than just different serializers

context

open as a page

How do you configure serializers on a RedisTemplate, and why is the choice important?

level: middleimportance: must knowfreq 60%

basics

~10 s

Define a RedisTemplate bean and call setKeySerializer/setValueSerializer (and the hash variants). Common choices: StringRedisSerializer for keys and a JSON serializer for values, so data is readable and language-neutral.

open as a page

How do @RedisHash entities and Redis repositories work, and how are objects stored?

level: middleimportance: should knowfreq 45%

basics

~20 s

Annotate a class with @RedisHash and give it an @Id field, then declare a CrudRepository for it. Spring stores each object as a Redis hash under a key like keyspace:id, and save/findById/delete work like JPA.

open as a page

How do secondary indexes (@Indexed) enable derived queries on Redis repositories, and what are the costs?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Add @Indexed to a field; Spring keeps a Redis SET of ids per field value (like people:firstname:Ann). Then a derived finder such as findByFirstname reads that set. Without @Indexed you can't query by that field.

open as a page

When would you choose RedisTemplate over @RedisHash repositories, and what architectural tradeoffs drive that decision?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

Use RedisTemplate when you need control over the actual Redis structures — counters, queues, sorted sets, atomic ops, pub/sub, or custom keys. Use @RedisHash repositories for simple id-keyed aggregates with a JPA-like API and a few indexed lookups.

open as a page