Skip to content

Commit d063552

Browse files
christophstroblmp911de
authored andcommitted
Add support for Jackson 3-based HashMapper and RedisSerializer.
We now support Jackson 3 through a separate Jackson3HashMapper, Jackson3JsonRedisSerializer, and GenericJackson3JsonRedisSerializer. Jackson 3 uses different defaults than Jackson 2 did therefore, we also provide configuration variants that reflect Jackson 2 behavior for smoother upgrade paths. Original pull request: #3168 Closes #3154
1 parent 3f4f9a9 commit d063552

26 files changed

+2943
-8
lines changed

pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,20 @@
149149
<optional>true</optional>
150150
</dependency>
151151

152+
<!-- jackson 3 -->
153+
<dependency>
154+
<groupId>tools.jackson.core</groupId>
155+
<artifactId>jackson-databind</artifactId>
156+
<optional>true</optional>
157+
</dependency>
158+
159+
<dependency>
160+
<groupId>com.fasterxml.jackson.core</groupId>
161+
<artifactId>jackson-annotations</artifactId>
162+
<version>3.0-rc5</version>
163+
<optional>true</optional>
164+
</dependency>
165+
152166
<dependency>
153167
<groupId>commons-beanutils</groupId>
154168
<artifactId>commons-beanutils</artifactId>

src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[[redis.hashmappers.root]]
22
= Hash Mapping
33

4-
Data can be stored by using various data structures within Redis. javadoc:org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer[] can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case):
4+
Data can be stored by using various data structures within Redis. javadoc:org.springframework.data.redis.serializer.Jackson3JsonRedisSerializer[] can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case):
55

66
* Direct mapping, by using javadoc:org.springframework.data.redis.core.HashOperations[] and a xref:redis.adoc#redis:serializer[serializer]
77
* Using xref:repositories.adoc[Redis Repositories]
@@ -16,7 +16,8 @@ Multiple implementations are available:
1616

1717
* javadoc:org.springframework.data.redis.hash.BeanUtilsHashMapper[] using Spring's {spring-framework-javadoc}/org/springframework/beans/BeanUtils.html[BeanUtils].
1818
* javadoc:org.springframework.data.redis.hash.ObjectHashMapper[] using xref:redis/redis-repositories/mapping.adoc[Object-to-Hash Mapping].
19-
* <<redis.hashmappers.jackson2,`Jackson2HashMapper`>> using https://github.com/FasterXML/jackson[FasterXML Jackson].
19+
* <<redis.hashmappers.jackson3,`Jackson3HashMapper`>> using https://github.com/FasterXML/jackson[FasterXML Jackson 3].
20+
* <<redis.hashmappers.jackson2,`Jackson2HashMapper`>> (deprecated) using https://github.com/FasterXML/jackson[FasterXML Jackson 2].
2021

2122
The following example shows one way to implement hash mapping:
2223

@@ -50,9 +51,91 @@ public class HashMapping {
5051
}
5152
----
5253

54+
[[redis.hashmappers.jackson3]]
55+
=== Jackson3HashMapper
56+
57+
javadoc:org.springframework.data.redis.hash.Jackson3HashMapper[] provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson 3].
58+
`Jackson3HashMapper` can map top-level properties as Hash field names and, optionally, flatten the structure.
59+
Simple types map to simple values. Complex types (nested objects, collections, maps, and so on) are represented as nested JSON.
60+
61+
Flattening creates individual hash entries for all nested properties and resolves complex types into simple types, as far as possible.
62+
63+
Consider the following class and the data structure it contains:
64+
65+
[source,java]
66+
----
67+
public class Person {
68+
String firstname;
69+
String lastname;
70+
Address address;
71+
Date date;
72+
LocalDateTime localDateTime;
73+
}
74+
75+
public class Address {
76+
String city;
77+
String country;
78+
}
79+
----
80+
81+
The following table shows how the data in the preceding class would appear in normal mapping:
82+
83+
.Normal Mapping
84+
[width="80%",cols="<1,<2",options="header"]
85+
|====
86+
|Hash Field
87+
|Value
88+
89+
|firstname
90+
|`Jon`
91+
92+
|lastname
93+
|`Snow`
94+
95+
|address
96+
|`{ "city" : "Castle Black", "country" : "The North" }`
97+
98+
|date
99+
|1561543964015
100+
101+
|localDateTime
102+
|`2018-01-02T12:13:14`
103+
|====
104+
105+
The following table shows how the data in the preceding class would appear in flat mapping:
106+
107+
.Flat Mapping
108+
[width="80%",cols="<1,<2",options="header"]
109+
|====
110+
|Hash Field
111+
|Value
112+
113+
|firstname
114+
|`Jon`
115+
116+
|lastname
117+
|`Snow`
118+
119+
|address.city
120+
|`Castle Black`
121+
122+
|address.country
123+
|`The North`
124+
125+
|date
126+
|1561543964015
127+
128+
|localDateTime
129+
|`2018-01-02T12:13:14`
130+
|====
131+
132+
NOTE: Flattening requires all property names to not interfere with the JSON path. Using dots or brackets in map keys or as property names is not supported when you use flattening. The resulting hash cannot be mapped back into an Object.
133+
53134
[[redis.hashmappers.jackson2]]
54135
=== Jackson2HashMapper
55136

137+
WARNING: Jackson 2 based implementations have been deprecated and are subject to removal in a subsequent release.
138+
56139
javadoc:org.springframework.data.redis.hash.Jackson2HashMapper[] provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson].
57140
`Jackson2HashMapper` can map top-level properties as Hash field names and, optionally, flatten the structure.
58141
Simple types map to simple values. Complex types (nested objects, collections, maps, and so on) are represented as nested JSON.

src/main/antora/modules/ROOT/pages/redis/redis-repositories/mapping.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ The following example shows two sample byte array converters:
9292
@WritingConverter
9393
public class AddressToBytesConverter implements Converter<Address, byte[]> {
9494
95-
private final Jackson2JsonRedisSerializer<Address> serializer;
95+
private final Jackson3JsonRedisSerializer<Address> serializer;
9696
9797
public AddressToBytesConverter() {
9898
99-
serializer = new Jackson2JsonRedisSerializer<Address>(Address.class);
99+
serializer = new Jackson3JsonRedisSerializer<Address>(Address.class);
100100
serializer.setObjectMapper(new ObjectMapper());
101101
}
102102
@@ -109,11 +109,11 @@ public class AddressToBytesConverter implements Converter<Address, byte[]> {
109109
@ReadingConverter
110110
public class BytesToAddressConverter implements Converter<byte[], Address> {
111111
112-
private final Jackson2JsonRedisSerializer<Address> serializer;
112+
private final Jackson3JsonRedisSerializer<Address> serializer;
113113
114114
public BytesToAddressConverter() {
115115
116-
serializer = new Jackson2JsonRedisSerializer<Address>(Address.class);
116+
serializer = new Jackson3JsonRedisSerializer<Address>(Address.class);
117117
serializer.setObjectMapper(new ObjectMapper());
118118
}
119119

src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ You may provide a `HashMapper` suitable for your requirements when obtaining `St
291291
[source,java]
292292
----
293293
redisTemplate()
294-
.opsForStream(new Jackson2HashMapper(true))
294+
.opsForStream(new Jackson3HashMapper(true))
295295
.add(record); <1>
296296
----
297297
<1> XADD user-logon * "firstname" "night" "@class" "com.example.User" "lastname" "angel"

src/main/antora/modules/ROOT/pages/redis/template.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ Multiple implementations are available (including two that have been already men
365365
* javadoc:org.springframework.data.redis.serializer.JdkSerializationRedisSerializer[], which is used by default for javadoc:org.springframework.data.redis.cache.RedisCache[] and javadoc:org.springframework.data.redis.core.RedisTemplate[].
366366
* the `StringRedisSerializer`.
367367

368-
However, one can use `OxmSerializer` for Object/XML mapping through Spring {spring-framework-docs}/data-access.html#oxm[OXM] support or javadoc:org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer[] or javadoc:org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer[] for storing data in https://en.wikipedia.org/wiki/JSON[JSON] format.
368+
However, one can use `OxmSerializer` for Object/XML mapping through Spring {spring-framework-docs}/data-access.html#oxm[OXM] support or javadoc:org.springframework.data.redis.serializer.Jackson3JsonRedisSerializer[] or javadoc:org.springframework.data.redis.serializer.GenericJackson3JsonRedisSerializer[] for storing data in https://en.wikipedia.org/wiki/JSON[JSON] format.
369369

370370
Do note that the storage format is not limited only to values.
371371
It can be used for keys, values, or hashes without any restrictions.

src/main/java/org/springframework/data/redis/hash/Jackson2HashMapper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@
143143
* @author Mark Paluch
144144
* @author John Blum
145145
* @since 1.8
146+
* @deprecated since 4.0
146147
*/
148+
@Deprecated(since = "4.0", forRemoval = true)
147149
public class Jackson2HashMapper implements HashMapper<Object, String, Object> {
148150

149151
private static final boolean SOURCE_VERSION_PRESENT =

0 commit comments

Comments
 (0)