Retain target type hint when deserializing Stream records.
We now retain the target type when obtaining a HashMapper through StreamObjectMapper. To achieve this, we introduced the HashObjectReader interface accepting a target type. Resolves: #2198 Related: #1566 Original Pull Request: #2253
This commit is contained in:
committed by
Christoph Strobl
parent
1932a4ca27
commit
73b49862df
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.redis.hash.Jackson2HashMapper;
|
||||
import org.springframework.data.redis.hash.ObjectHashMapper;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link StreamObjectMapper}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class StreamObjectMapperUnitTests {
|
||||
|
||||
@Test // GH-2198
|
||||
void shouldRetainTypeHintUsingObjectHashMapper() {
|
||||
|
||||
StreamObjectMapper mapper = new StreamObjectMapper(ObjectHashMapper.getSharedInstance());
|
||||
|
||||
MyType result = mapper.getHashMapper(MyType.class)
|
||||
.fromHash(Collections.singletonMap("value".getBytes(), "hello".getBytes()));
|
||||
|
||||
assertThat(result.value).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@Test // GH-2198
|
||||
void shouldRetainTypeHintUsingJackson() {
|
||||
|
||||
StreamObjectMapper mapper = new StreamObjectMapper(new Jackson2HashMapper(true));
|
||||
|
||||
MyType result = mapper.getHashMapper(MyType.class).fromHash(Collections.singletonMap("value", "hello"));
|
||||
|
||||
assertThat(result.value).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@Data
|
||||
static class MyType {
|
||||
String value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 the original author or authors.
|
||||
* Copyright 2016-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.mapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@@ -48,13 +50,13 @@ public abstract class Jackson2HashMapperUnitTests extends AbstractHashMapperTest
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
static class FlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
|
||||
public static class FlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
|
||||
FlatteningJackson2HashMapperUnitTests() {
|
||||
super(new Jackson2HashMapper(true));
|
||||
}
|
||||
}
|
||||
|
||||
static class NonFlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
|
||||
public static class NonFlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
|
||||
|
||||
NonFlatteningJackson2HashMapperUnitTests() {
|
||||
super(new Jackson2HashMapper(false));
|
||||
@@ -183,6 +185,24 @@ public abstract class Jackson2HashMapperUnitTests extends AbstractHashMapperTest
|
||||
assertBackAndForwardMapping(source);
|
||||
}
|
||||
|
||||
@Test // GH-2198
|
||||
void shouldDeserializeObjectWithoutClassHint() {
|
||||
|
||||
WithDates source = new WithDates();
|
||||
source.string = "id-1";
|
||||
source.date = new Date(1561543964015L);
|
||||
source.calendar = Calendar.getInstance();
|
||||
source.localDate = LocalDate.parse("2018-01-02");
|
||||
source.localDateTime = LocalDateTime.parse("2018-01-02T12:13:14");
|
||||
|
||||
Map<String, Object> map = mapper.toHash(source);
|
||||
|
||||
// ensure that we remove the correct type hint
|
||||
assertThat(map.remove("@class")).isNotNull();
|
||||
|
||||
assertThat(mapper.fromHash(WithDates.class, map)).isEqualTo(source);
|
||||
}
|
||||
|
||||
@Test // GH-1566
|
||||
void mapFinalClass() {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -83,6 +84,18 @@ class ObjectHashMapperTests extends AbstractHashMapperTests {
|
||||
assertThat(objectHashMapper.fromHash(hash)).isEqualTo(source);
|
||||
}
|
||||
|
||||
@Test // GH-2198
|
||||
void readHashConsidersTypeHint() {
|
||||
|
||||
Map<byte[], byte[]> hash = new LinkedHashMap<>();
|
||||
hash.put("value".getBytes(), "hello".getBytes());
|
||||
|
||||
ObjectHashMapper objectHashMapper = ObjectHashMapper.getSharedInstance();
|
||||
WithTypeAlias withTypeAlias = objectHashMapper.fromHash(WithTypeAlias.class, hash);
|
||||
|
||||
assertThat(withTypeAlias.value).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@TypeAlias("_42_")
|
||||
@Data
|
||||
static class WithTypeAlias {
|
||||
|
||||
Reference in New Issue
Block a user