diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java index 7639ed704..8387c45be 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java @@ -27,7 +27,6 @@ import java.util.Set; class DefaultBoundHashOperations extends DefaultKeyBound implements BoundHashOperations { private final HashOperations ops; - private RedisOperations template; /** * Constructs a new DefaultBoundHashOperations instance. @@ -52,7 +51,7 @@ class DefaultBoundHashOperations extends DefaultKeyBound implement @Override public RedisOperations getOperations() { - return template; + return ops.getOperations(); } @Override diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java index 82618e745..23755be71 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java @@ -43,4 +43,6 @@ public interface HashOperations { void set(H key, HK hashKey, HV value); Collection values(H key); + + RedisOperations getOperations(); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java index 01b7d0e70..fd44f0b59 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java @@ -56,7 +56,8 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation private boolean exposeConnection = false; private RedisSerializer keySerializer = new StringRedisSerializer(); private RedisSerializer valueSerializer = new SimpleRedisSerializer(); - private RedisSerializer defaultSerializer = new SimpleRedisSerializer(); + private RedisSerializer hashKeySerializer = new SimpleRedisSerializer(); + private RedisSerializer hashValueSerializer = new SimpleRedisSerializer(); public RedisTemplate() { } @@ -82,7 +83,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } public T execute(RedisCallback action, boolean exposeConnection) { - return execute(action, isExposeConnection(), defaultSerializer); + return execute(action, isExposeConnection(), valueSerializer); } public T execute(RedisCallback action, boolean exposeConnection, RedisSerializer returnSerializer) { @@ -133,18 +134,43 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation this.exposeConnection = exposeConnection; } + /** + * Sets the key serializer to be used by this template. Defaults to {@link SimpleRedisSerializer}. + * + * @param serializer + */ public void setKeySerializer(RedisSerializer serializer) { this.keySerializer = serializer; } + /** + * Sets the value serializer to be used by this template. Defaults to {@link SimpleRedisSerializer}. + * + * @param serializer + */ public void setValueSerializer(RedisSerializer serializer) { this.valueSerializer = serializer; } - public void setDefaultSerializer(RedisSerializer serializer) { - this.defaultSerializer = serializer; + /** + * Sets the hash key (or field) serializer to be used by this template. Defaults to {@link SimpleRedisSerializer}. + * + * @param hashKeySerializer The hashKeySerializer to set. + */ + public void setHashKeySerializer(RedisSerializer hashKeySerializer) { + this.hashKeySerializer = hashKeySerializer; } + /** + * Sets the hash value serializer to be used by this template. Defaults to {@link SimpleRedisSerializer}. + * + * @param hashValueSerializer The hashValueSerializer to set. + */ + public void setHashValueSerializer(RedisSerializer hashValueSerializer) { + this.hashValueSerializer = hashValueSerializer; + } + + /** * Invocation handler that suppresses close calls on JDO PersistenceManagers. * Also prepares returned Query objects. @@ -207,7 +233,9 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation Collection values = (List.class.isAssignableFrom(type) ? new ArrayList(rawValues.size()) : new LinkedHashSet(rawValues.size())); for (byte[] bs : rawValues) { - values.add((V) valueSerializer.deserialize(bs)); + if (bs != null) { + values.add((V) valueSerializer.deserialize(bs)); + } } return (T) values; @@ -218,21 +246,49 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation Collection values = (List.class.isAssignableFrom(type) ? new ArrayList(rawValues.size()) : new LinkedHashSet(rawValues.size())); for (byte[] bs : rawValues) { - values.add((H) valueSerializer.deserialize(bs)); + if (bs != null) { + values.add((H) valueSerializer.deserialize(bs)); + } } return values; } + @SuppressWarnings("unchecked") + private K deserializeKey(byte[] value) { + return (K) deserialize(value, keySerializer); + } + + @SuppressWarnings("unchecked") + private V deserializeValue(byte[] value) { + return (V) deserialize(value, valueSerializer); + } + + @SuppressWarnings("unchecked") + private HK deserializeHashKey(byte[] value) { + return (HK) deserialize(value, hashKeySerializer); + } + + @SuppressWarnings("unchecked") + private HV deserializeHashValue(byte[] value) { + return (HV) deserialize(value, hashValueSerializer); + } + + private T deserialize(byte[] value, RedisSerializer serializer) { + if (isEmpty(value)) { + return null; + } + return (T) serializer.deserialize(value); + } + + private static boolean isEmpty(byte[] data) { + return (data == null || data.length == 0); + } + // utility methods for the template internal methods private abstract class ValueDeserializingRedisCallback implements RedisCallback { private K key; - public ValueDeserializingRedisCallback() { - this(null); - - } - public ValueDeserializingRedisCallback(K key) { this.key = key; } @@ -241,10 +297,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public final V doInRedis(RedisConnection connection) { byte[] result = inRedis(rawKey(key), connection); - if (result != null) { - return (V) valueSerializer.deserialize(result); - } - return null; + return deserializeValue(result); } protected abstract byte[] inRedis(byte[] rawKey, RedisConnection connection); @@ -558,7 +611,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation public void diffAndStore(final K key, K destKey, final K... keys) { final byte[][] rawKeys = rawKeys(aggregateKeys(key, keys)); final byte[] rawDestKey = rawKey(destKey); - Object rawValues = execute(new RedisCallback() { + execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) { connection.sDiffStore(rawDestKey, rawKeys); @@ -881,6 +934,11 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation private class DefaultHashOperations implements HashOperations { + @Override + public RedisOperations getOperations() { + return RedisTemplate.this; + } + @Override public HV get(K key, Object hashKey) { final byte[] rawKey = rawKey(key); @@ -893,7 +951,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } }, true); - return (HV) valueSerializer.deserialize(rawHashValue); + return deserializeHashValue(rawHashValue); } @Override diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java index e1b3440ea..5e84e389f 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java @@ -31,10 +31,21 @@ public class DefaultRedisMap implements RedisMap { private final BoundHashOperations hashOps; + /** + * Constructs a new DefaultRedisMap instance. + * + * @param key + * @param operations + */ public DefaultRedisMap(String key, RedisOperations operations) { this.hashOps = operations.forHash(key); } + /** + * Constructs a new DefaultRedisMap instance. + * + * @param boundOps + */ public DefaultRedisMap(BoundHashOperations boundOps) { this.hashOps = boundOps; }