-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
This is a test which passes with Spring Data Redis 3.5.1
:
@Test
void listAsRecordValueInStream() {
String streamKey = "test-stream";
List<String> input = Arrays.asList("Hello", "stream", "message");
ReactiveRedisTemplate<String, ?> template =
new ReactiveRedisTemplate<>(this.redisConnectionFactory, RedisSerializationContext.string());
ReactiveStreamOperations<String, Object, Object> streamOperations = template.opsForStream();
@SuppressWarnings("unchecked")
Mono<List<?>> result =
streamOperations.add(StreamRecords.objectBacked(input).withStreamKey(streamKey))
.thenMany(streamOperations.read(List.class, StreamOffset.fromStart(streamKey)))
.next()
.map(Record::getValue);
StepVerifier.create(result)
.expectNext(input)
.verifyComplete();
}
In debug, on the StreamObjectMapper.toObjectRecord()
, I see the value like:
source = {StreamRecords$MapBackedRecord@9126} "MapBackedRecord{recordId=1752698244313-0, kvMap={[0]=Hello, [0]._class=java.lang.String, [1]=stream, [1]._class=java.lang.String, [2]=message, [2]._class=java.lang.String, _class=java.util.Arrays$ArrayList}}"
stream = "test-stream"
recordId = {RecordId@9194} "1752698244313-0"
kvMap = {LinkedHashMap@9195} size = 7
"[0]" -> "Hello"
"[0]._class" -> "java.lang.String"
"[1]" -> "stream"
"[1]._class" -> "java.lang.String"
"[2]" -> "message"
"[2]._class" -> "java.lang.String"
"_class" -> "java.util.Arrays$ArrayList"
With latest Spring Data Redis 4.0.0-SNAPSHOT
, the test fails like:
Suppressed: java.lang.IllegalArgumentException: Value must not be null
at org.springframework.util.Assert.notNull(Assert.java:182)
at org.springframework.data.redis.connection.stream.Record.of(Record.java:99)
at org.springframework.data.redis.connection.stream.MapRecord.toObjectRecord(MapRecord.java:140)
at org.springframework.data.redis.core.StreamObjectMapper.toObjectRecord(StreamObjectMapper.java:137)
at org.springframework.data.redis.core.ReactiveStreamOperations.map(ReactiveStreamOperations.java:696)
at org.springframework.data.redis.core.ReactiveStreamOperations.lambda$read$0(ReactiveStreamOperations.java:536)
where in debug at the same spot I see the value as:
record = {StreamRecords$MapBackedRecord@9470} "MapBackedRecord{recordId=1752698947969-0, kvMap={[0]=Hello, [0]._class=java.lang.String, [1]=stream, [1]._class=java.lang.String, [2]=message, [2]._class=java.lang.String}}"
stream = "test-stream"
recordId = {RecordId@9523} "1752698947969-0"
kvMap = {LinkedHashMap@9524} size = 6
"[0]" -> "Hello"
"[0]._class" -> "java.lang.String"
"[1]" -> "stream"
"[1]._class" -> "java.lang.String"
"[2]" -> "message"
"[2]._class" -> "java.lang.String"
Pay attention that there is no top-level _class
entry in the map.
Looks like MappingRedisConverter.write(Object source, RedisData sink)
has suffered some changes and there is no typeMapper.writeType(ClassUtils.getUserClass(source), sink.getBucket().getPath());
to put that _class
entry into the target KV.
With the latest change we just have some optimization for collections:
if (source instanceof Collection collection) {
writeCollection(sink.getKeyspace(), "", collection, TypeInformation.of(Object.class), sink);
return;
}
Probably a side effect after: #2168.
The MappingRedisConverter.read(Class<R> type, RedisData source)
in 3.5.1
picks up that _class
from KV easy.
In 4.0.0-SNAPSHOT
, it gets null for that typeMapper.readType()
. And I believe just because there is no that _class
entry stored in the target KV.
Thanks