DATAREDIS-1179 - Allow reuse of RedisConverter in ObjectHashMapper.

Original pull request: #548.
This commit is contained in:
Christoph Strobl
2020-07-14 13:14:20 +02:00
committed by Mark Paluch
parent f92ed7632d
commit 59065ab0bc
3 changed files with 81 additions and 7 deletions

View File

@@ -293,3 +293,37 @@ redisTemplate()
.add(record); <1>
----
<1> XADD user-logon * "firstname" "night" "@class" "com.example.User" "lastname" "angel"
[NOTE]
====
A `StreamMessageListenerContainer` may not be aware of any `@TypeAlias` used on domain types as those need to be resolved via a `MappingContext`. So please make sure to pre initialize the `RedisMappingContext` with the `initialEntitySet`.
[source,java]
----
@Bean
RedisMappingContext redisMappingContext() {
RedisMappingContext ctx = new RedisMappingContext();
ctx.setInitialEntitySet(Collections.singleton(Person.class));
return ctx;
}
@Bean
RedisConverter redisConverter(RedisMappingContext mappingContext) {
return new MappingRedisConverter(mappingContext, null, null);
}
@Bean
ObjectHashMapper hashMapper(RedisConverter converter) {
return new ObjectHashMapper(converter);
}
@Bean
StreamMessageListenerContainer streamMessageListenerContainer(RedisConnectionFactory connectionFactory, ObjectHashMapper hashMapper) {
StreamMessageListenerContainerOptions<String, ObjectRecord<String, Object>> options = StreamMessageListenerContainerOptions.builder()
.objectMapper(hashMapper)
.build();
return StreamMessageListenerContainer.create(connectionFactory, options);
}
----
====

View File

@@ -16,24 +16,21 @@
package org.springframework.data.redis.hash;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.data.redis.core.convert.CustomConversions;
import org.springframework.data.redis.core.convert.IndexResolver;
import org.springframework.data.redis.core.convert.IndexedData;
import org.springframework.data.redis.core.convert.MappingRedisConverter;
import org.springframework.data.redis.core.convert.RedisConverter;
import org.springframework.data.redis.core.convert.RedisCustomConversions;
import org.springframework.data.redis.core.convert.RedisData;
import org.springframework.data.redis.core.convert.ReferenceResolver;
import org.springframework.data.redis.core.mapping.RedisMappingContext;
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@link HashMapper} based on {@link MappingRedisConverter}. Supports nested properties and simple types like
@@ -74,7 +71,7 @@ import org.springframework.lang.Nullable;
*/
public class ObjectHashMapper implements HashMapper<Object, byte[], byte[]> {
private final MappingRedisConverter converter;
private final RedisConverter converter;
/**
* Creates new {@link ObjectHashMapper}.
@@ -110,6 +107,19 @@ public class ObjectHashMapper implements HashMapper<Object, byte[], byte[]> {
converter = mappingConverter;
}
/**
* Creates a new {@link ObjectHashMapper} using the given {@link RedisConverter} for conversion.
*
* @param converter must not be {@literal null}.
* @throws IllegalArgumentException if the given {@literal converter} is {@literal null}.
* @since 2.4
*/
public ObjectHashMapper(RedisConverter converter) {
Assert.notNull(converter, "Converter must not be null!");
this.converter = converter;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.hash.HashMapper#toHash(java.lang.Object)

View File

@@ -17,10 +17,15 @@ package org.springframework.data.redis.mapping;
import static org.assertj.core.api.Assertions.*;
import lombok.Data;
import java.util.Collections;
import java.util.Map;
import org.junit.Test;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.redis.core.convert.MappingRedisConverter;
import org.springframework.data.redis.core.mapping.RedisMappingContext;
import org.springframework.data.redis.hash.ObjectHashMapper;
/**
@@ -57,4 +62,29 @@ public class ObjectHashMapperTests extends AbstractHashMapperTest {
String result = objectHashMapper.fromHash(hash, String.class);
}
@Test // DATAREDIS-1179
public void hashMapperAllowsReuseOfRedisConverter/*and thus the MappingContext holding eg. TypeAlias information*/() {
WithTypeAlias source = new WithTypeAlias();
source.value = "val";
Map<byte[], byte[]> hash = new ObjectHashMapper().toHash(source);
RedisMappingContext ctx = new RedisMappingContext();
ctx.setInitialEntitySet(Collections.singleton(WithTypeAlias.class));
ctx.afterPropertiesSet();
MappingRedisConverter mappingRedisConverter = new MappingRedisConverter(ctx, null, null);
mappingRedisConverter.afterPropertiesSet();
ObjectHashMapper objectHashMapper = new ObjectHashMapper(mappingRedisConverter);
assertThat(objectHashMapper.fromHash(hash)).isEqualTo(source);
}
@TypeAlias("_42_")
@Data
static class WithTypeAlias {
String value;
}
}