Files
spring-boot-demo/redis/docs/03-string-template-and-two-keyspaces.md

51 lines
2.5 KiB
Markdown

[Home](../README.md) | Prev: [Default serialization](02-default-serialization.md) | Next: [JSON serializers](04-json-serializers.md)
# 3. StringRedisTemplate, and why two templates do not share keys
`StringRedisTemplate` is the template Boot registers for text. Keys, values, hash keys and hash
values all go through `StringRedisSerializer`, which is UTF-8 in and out
([04-string-template.txt](output/04-string-template.txt)):
```
key serializer: StringRedisSerializer
value serializer: StringRedisSerializer
hash key serializer: StringRedisSerializer
hash value serializer: StringRedisSerializer
```
Everything is then readable from `redis-cli`: strings, counters (`INCR` works and can be read back),
hashes (`opsForHash`), lists, sets and sorted sets. The transcript shows each one.
## Two templates, two keyspaces
The important thing about a serializer is that it is part of the **key**. Write `user:1` with the
`StringRedisTemplate` and read it with the default `RedisTemplate`, and you get `null`, because the
default template looks for a different byte sequence
([05-two-templates-two-keyspaces.txt](output/05-two-templates-two-keyspaces.txt)):
```
stringTemplate.opsForValue().get("user:1") = from-string-template
redisTemplate.opsForValue().get("user:1") = null
```
Write it through both and Redis holds two entries (`DBSIZE` is 2), only one of which `redis-cli GET user:1` can see.
This is one way to end up with "my cache works in one service and misses in another": two services,
two templates, one Redis, and keys that only look the same in the logs.
The fix is a rule, not a class: pick one key serializer per Redis and put it in one shared
configuration. `StringRedisSerializer` for keys is what you want unless you have a reason, and every
template in [JsonRedisConfig](../src/main/java/com/ankurm/redis/config/JsonRedisConfig.java) does that.
## When StringRedisTemplate is enough
Counters, flags, locks, session ids, anything you would be happy to `GET` by hand. If you find
yourself calling `objectMapper.writeValueAsString` before every `set`, you are doing by hand what a
JSON value serializer does ([chapter 4](04-json-serializers.md)).
## Going deeper
- [StringTemplateTest](../src/test/java/com/ankurm/redis/StringTemplateTest.java)
- [Spring Data Redis: RedisTemplate and StringRedisTemplate](https://docs.spring.io/spring-data/redis/reference/redis/template.html)
[Home](../README.md) | Prev: [Default serialization](02-default-serialization.md) | Next: [JSON serializers](04-json-serializers.md)