Fix Jackson (hash) mapping for BigDecimal/BigInteger scalar values and Java Time types.

Once again, the SD Redis Jackson2HashMapper can now de/serialize Objects with BigDecimal/BigInteger values along with java.time types, such as java.time.LocalDateTime.

Additionally, splits the unit tests for flattening and unflattening of the hash mapping into 2 separate test classes to be picked up in the SD Redis test suite.

Resolves #2593
This commit is contained in:
Christoph Strobl
2023-06-06 10:27:02 +02:00
committed by John Blum
parent 770fbac670
commit 637964eed8
4 changed files with 75 additions and 18 deletions

View File

@@ -54,6 +54,7 @@ import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -183,6 +184,10 @@ public class Jackson2HashMapper implements HashMapper<Object, String, Object> {
return false;
}
if(flatten && t.isTypeOrSubTypeOf(Number.class)) {
return false;
}
if (EVERYTHING.equals(_appliesFor)) {
return !TreeNode.class.isAssignableFrom(t.getRawClass());
}
@@ -196,6 +201,9 @@ public class Jackson2HashMapper implements HashMapper<Object, String, Object> {
typingMapper.activateDefaultTyping(typingMapper.getPolymorphicTypeValidator(), DefaultTyping.EVERYTHING,
As.PROPERTY);
typingMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
if(flatten) {
typingMapper.disable(MapperFeature.REQUIRE_TYPE_ID_FOR_SUBTYPES);
}
// Prevent splitting time types into arrays. E
typingMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
@@ -240,7 +248,7 @@ public class Jackson2HashMapper implements HashMapper<Object, String, Object> {
Map<String, Object> unflattenedHash = doUnflatten(hash);
byte[] unflattenedHashedBytes = untypedMapper.writeValueAsBytes(unflattenedHash);
Object hashedObject = typingMapper.reader().forType(Object.class)
.readValue(unflattenedHashedBytes);;
.readValue(unflattenedHashedBytes);
return hashedObject;
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2023 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.mapping;
import org.springframework.data.redis.hash.Jackson2HashMapper;
/**
* @author Christoph Strobl
* @since 2023/06
*/
public class Jackson2HashMapperFlatteningUnitTests extends Jackson2HashMapperUnitTests {
Jackson2HashMapperFlatteningUnitTests() {
super(new Jackson2HashMapper(true));
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2023 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.mapping;
import org.springframework.data.redis.hash.Jackson2HashMapper;
/**
* @author Christoph Strobl
* @since 2023/06
*/
public class Jackson2HashMapperNonFlatteningUnitTests extends Jackson2HashMapperUnitTests {
Jackson2HashMapperNonFlatteningUnitTests() {
super(new Jackson2HashMapper(false));
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.mapping;
import static org.assertj.core.api.Assertions.*;
import lombok.Data;
import java.math.BigDecimal;
@@ -28,9 +30,11 @@ import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.springframework.data.redis.Address;
import org.springframework.data.redis.Person;
import org.springframework.data.redis.hash.HashMapper;
@@ -44,23 +48,10 @@ import org.springframework.data.redis.hash.Jackson2HashMapper;
*/
public abstract class Jackson2HashMapperUnitTests extends AbstractHashMapperTests {
private final Jackson2HashMapper mapper;
private Jackson2HashMapper mapper;
Jackson2HashMapperUnitTests(Jackson2HashMapper mapper) {
this.mapper = mapper;
}
static class FlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
FlatteningJackson2HashMapperUnitTests() {
super(new Jackson2HashMapper(true));
}
}
static class NonFlatteningJackson2HashMapperUnitTests extends Jackson2HashMapperUnitTests {
NonFlatteningJackson2HashMapperUnitTests() {
super(new Jackson2HashMapper(false));
}
public Jackson2HashMapperUnitTests(Jackson2HashMapper param){
this.mapper = param;
}
@Override