DATAREDIS-503 - Add HashMapper implementation based on MappingRedisConverter.
We now support mapping of simple and complex types to Redis HASH structures applying the same structure as the Repository support. This allows Object to hash Mapping and its direct usage via RedisTemplate without the need of explicitly having to use the repository abstraction. Original pull request: #194.
This commit is contained in:
committed by
Mark Paluch
parent
f5ecd3a9b1
commit
359c3e4533
@@ -344,6 +344,14 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
if (!customConversions.hasCustomWriteTarget(source.getClass())) {
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink);
|
||||
}
|
||||
|
||||
if (entity == null) {
|
||||
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink);
|
||||
sink.getBucket().put("_raw", conversionService.convert(source, byte[].class));
|
||||
return;
|
||||
}
|
||||
|
||||
sink.setKeyspace(entity.getKeySpace());
|
||||
|
||||
writeInternal(entity.getKeySpace(), "", source, entity.getTypeInformation(), sink);
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2016 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
|
||||
*
|
||||
* http://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.hash;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.RedisData;
|
||||
import org.springframework.data.redis.core.convert.ReferenceResolver;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* {@link HashMapper} based on {@link MappingRedisConverter}. Does supports nested properties and simple types like
|
||||
* {@link String}.
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* class Person {
|
||||
*
|
||||
* String firstname;
|
||||
*
|
||||
* List<String> nicknames;
|
||||
* List<Person> coworkers;
|
||||
*
|
||||
* Address address;
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* The above is represented as:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* _class=org.example.Person
|
||||
* firstname=rand
|
||||
* lastname=al'thor
|
||||
* coworkers.[0].firstname=mat
|
||||
* coworkers.[0].nicknames.[0]=prince of the ravens
|
||||
* coworkers.[1].firstname=perrin
|
||||
* coworkers.[1].address.city=two rivers
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 1.8
|
||||
*/
|
||||
public class ConvertingHashMapper implements HashMapper<Object, byte[], byte[]> {
|
||||
|
||||
private final MappingRedisConverter converter;
|
||||
|
||||
/**
|
||||
* Creates new {@link ConvertingHashMapper}.
|
||||
*/
|
||||
public ConvertingHashMapper() {
|
||||
this(new CustomConversions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link ConvertingHashMapper}.
|
||||
*
|
||||
* @param customConversions can be {@literal null}.
|
||||
*/
|
||||
public ConvertingHashMapper(CustomConversions customConversions) {
|
||||
|
||||
MappingRedisConverter mappingConverter = new MappingRedisConverter(new RedisMappingContext(),
|
||||
new NoOpIndexResolver(), new NoOpReferenceResolver());
|
||||
mappingConverter.setCustomConversions(customConversions == null ? new CustomConversions() : customConversions);
|
||||
mappingConverter.afterPropertiesSet();
|
||||
|
||||
converter = mappingConverter;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.hash.HashMapper#toHash(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Map<byte[], byte[]> toHash(Object source) {
|
||||
|
||||
if (source == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
RedisData sink = new RedisData();
|
||||
converter.write(source, sink);
|
||||
return sink.getBucket().rawMap();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.hash.HashMapper#fromHash(java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
public Object fromHash(Map<byte[], byte[]> hash) {
|
||||
|
||||
if (hash == null || hash.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return converter.read(Object.class, new RedisData(hash));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ReferenceResolver} implementation always returning an empty {@link Map}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
private static class NoOpReferenceResolver implements ReferenceResolver {
|
||||
|
||||
private static final Map<byte[], byte[]> NO_REFERENCE = Collections.emptyMap();
|
||||
|
||||
@Override
|
||||
public Map<byte[], byte[]> resolveReference(Serializable id, String keyspace) {
|
||||
return NO_REFERENCE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link IndexResolver} always returning an empty {@link Set}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
private static class NoOpIndexResolver implements IndexResolver {
|
||||
|
||||
private static final Set<IndexedData> NO_INDEXES = Collections.emptySet();
|
||||
|
||||
@Override
|
||||
public Set<IndexedData> resolveIndexesFor(TypeInformation<?> typeInformation, Object value) {
|
||||
return NO_INDEXES;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user