Skip to content

Commit aefd94b

Browse files
DATAREDIS-425 - ReferenceResolver just returns raw hash.
We removed the burden of converting raw hashes from ReferenceResolver and delegate this to the RedisConverter.
1 parent 2a522e5 commit aefd94b

File tree

8 files changed

+162
-103
lines changed

8 files changed

+162
-103
lines changed

src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
import org.springframework.data.redis.core.convert.PathIndexResolver;
4646
import org.springframework.data.redis.core.convert.RedisConverter;
4747
import org.springframework.data.redis.core.convert.RedisData;
48-
import org.springframework.data.redis.core.convert.ReferenceResolver;
48+
import org.springframework.data.redis.core.convert.ReferenceResolverImpl;
4949
import org.springframework.data.redis.core.mapping.RedisMappingContext;
5050
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
5151
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
@@ -86,8 +86,8 @@
8686
* @author Christoph Strobl
8787
* @since 1.7
8888
*/
89-
public class RedisKeyValueAdapter extends AbstractKeyValueAdapter implements ApplicationContextAware,
90-
ApplicationListener<RedisKeyspaceEvent> {
89+
public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
90+
implements ApplicationContextAware, ApplicationListener<RedisKeyspaceEvent> {
9191

9292
private static final Logger LOGGER = LoggerFactory.getLogger(RedisKeyValueAdapter.class);
9393

@@ -131,8 +131,8 @@ public RedisKeyValueAdapter(RedisOperations<?, ?> redisOps, RedisMappingContext
131131
Assert.notNull(redisOps, "RedisOperations must not be null!");
132132
Assert.notNull(mappingContext, "RedisMappingContext must not be null!");
133133

134-
MappingRedisConverter mappingConverter = new MappingRedisConverter(mappingContext, new PathIndexResolver(
135-
mappingContext), new ReferenceResolverImpl(this));
134+
MappingRedisConverter mappingConverter = new MappingRedisConverter(mappingContext,
135+
new PathIndexResolver(mappingContext), new ReferenceResolverImpl(redisOps));
136136
mappingConverter.setCustomConversions(customConversions == null ? new CustomConversions() : customConversions);
137137
mappingConverter.afterPropertiesSet();
138138

@@ -327,8 +327,8 @@ public List<Map<byte[], byte[]>> doInRedis(RedisConnection connection) throws Da
327327
Set<byte[]> members = connection.sMembers(binKeyspace);
328328

329329
for (byte[] id : members) {
330-
rawData.add(connection.hGetAll(createKey(asString(keyspace),
331-
getConverter().getConversionService().convert(id, String.class))));
330+
rawData.add(connection
331+
.hGetAll(createKey(asString(keyspace), getConverter().getConversionService().convert(id, String.class))));
332332
}
333333

334334
return rawData;
@@ -411,8 +411,8 @@ public void clear() {
411411
}
412412

413413
private String asString(Serializable value) {
414-
return value instanceof String ? (String) value : getConverter().getConversionService()
415-
.convert(value, String.class);
414+
return value instanceof String ? (String) value
415+
: getConverter().getConversionService().convert(value, String.class);
416416
}
417417

418418
public byte[] createKey(String keyspace, String id) {
@@ -544,8 +544,8 @@ public void onMessage(Message message, byte[] pattern) {
544544

545545
byte[] key = message.getBody();
546546

547-
final byte[] phantomKey = ByteUtils.concat(key, converter.getConversionService()
548-
.convert(":phantom", byte[].class));
547+
final byte[] phantomKey = ByteUtils.concat(key,
548+
converter.getConversionService().convert(":phantom", byte[].class));
549549

550550
Map<byte[], byte[]> hash = ops.execute(new RedisCallback<Map<byte[], byte[]>>() {
551551

@@ -580,40 +580,4 @@ private boolean isKeyExpirationMessage(Message message) {
580580
}
581581
}
582582

583-
/**
584-
* {@link ReferenceResolver} using {@link RedisKeyValueAdapter} to read and convert referenced entities.
585-
*
586-
* @author Christoph Strobl
587-
* @since 1.7
588-
*/
589-
static class ReferenceResolverImpl implements ReferenceResolver {
590-
591-
private RedisKeyValueAdapter adapter;
592-
593-
ReferenceResolverImpl() {}
594-
595-
/**
596-
* @param adapter must not be {@literal null}.
597-
*/
598-
public ReferenceResolverImpl(RedisKeyValueAdapter adapter) {
599-
this.adapter = adapter;
600-
}
601-
602-
/**
603-
* @param adapter
604-
*/
605-
public void setAdapter(RedisKeyValueAdapter adapter) {
606-
this.adapter = adapter;
607-
}
608-
609-
/*
610-
* (non-Javadoc)
611-
* @see org.springframework.data.redis.core.convert.ReferenceResolver#resolveReference(java.io.Serializable, java.io.Serializable, java.lang.Class)
612-
*/
613-
@Override
614-
public <T> T resolveReference(Serializable id, String keyspace, Class<T> type) {
615-
return (T) adapter.get(id, keyspace, type);
616-
}
617-
}
618-
619583
}

src/main/java/org/springframework/data/redis/core/RedisTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ public Set<byte[]> doInRedis(RedisConnection connection) {
722722
}
723723
}, true);
724724

725-
return keySerializer != null ? SerializationUtils.deserialize(rawKeys, keySerializer) : rawKeys;
725+
return keySerializer != null ? SerializationUtils.deserialize(rawKeys, keySerializer) : (Set<K>) rawKeys;
726726
}
727727

728728
public Boolean persist(K key) {

src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -210,35 +210,29 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
210210
if (persistentProperty.isMap()) {
211211

212212
if (conversionService.canConvert(byte[].class, persistentProperty.getMapValueType())) {
213-
accessor.setProperty(
214-
persistentProperty,
215-
readMapOfSimpleTypes(currentPath, persistentProperty.getType(), persistentProperty.getComponentType(),
216-
persistentProperty.getMapValueType(), source));
213+
accessor.setProperty(persistentProperty, readMapOfSimpleTypes(currentPath, persistentProperty.getType(),
214+
persistentProperty.getComponentType(), persistentProperty.getMapValueType(), source));
217215
} else {
218-
accessor.setProperty(
219-
persistentProperty,
220-
readMapOfComplexTypes(currentPath, persistentProperty.getType(), persistentProperty.getComponentType(),
221-
persistentProperty.getMapValueType(), source));
216+
accessor.setProperty(persistentProperty, readMapOfComplexTypes(currentPath, persistentProperty.getType(),
217+
persistentProperty.getComponentType(), persistentProperty.getMapValueType(), source));
222218
}
223219
}
224220

225221
else if (persistentProperty.isCollectionLike()) {
226222

227223
if (conversionService.canConvert(byte[].class, persistentProperty.getComponentType())) {
228-
accessor.setProperty(
229-
persistentProperty,
230-
readCollectionOfSimpleTypes(currentPath, persistentProperty.getType(), persistentProperty
231-
.getTypeInformation().getComponentType().getActualType().getType(), source));
224+
accessor.setProperty(persistentProperty,
225+
readCollectionOfSimpleTypes(currentPath, persistentProperty.getType(),
226+
persistentProperty.getTypeInformation().getComponentType().getActualType().getType(), source));
232227
} else {
233-
accessor.setProperty(
234-
persistentProperty,
235-
readCollectionOfComplexTypes(currentPath, persistentProperty.getType(), persistentProperty
236-
.getTypeInformation().getComponentType().getActualType().getType(), source.getBucket()));
228+
accessor.setProperty(persistentProperty,
229+
readCollectionOfComplexTypes(currentPath, persistentProperty.getType(),
230+
persistentProperty.getTypeInformation().getComponentType().getActualType().getType(),
231+
source.getBucket()));
237232
}
238233

239-
} else if (persistentProperty.isEntity()
240-
&& !conversionService.canConvert(byte[].class, persistentProperty.getTypeInformation().getActualType()
241-
.getType())) {
234+
} else if (persistentProperty.isEntity() && !conversionService.canConvert(byte[].class,
235+
persistentProperty.getTypeInformation().getActualType().getType())) {
242236

243237
Class<?> targetType = persistentProperty.getTypeInformation().getActualType().getType();
244238

@@ -284,8 +278,8 @@ private void readAssociation(final String path, final RedisData source, final Ke
284278
@Override
285279
public void doWithAssociation(Association<KeyValuePersistentProperty> association) {
286280

287-
String currentPath = !path.isEmpty() ? path + "." + association.getInverse().getName() : association
288-
.getInverse().getName();
281+
String currentPath = !path.isEmpty() ? path + "." + association.getInverse().getName()
282+
: association.getInverse().getName();
289283

290284
if (association.getInverse().isCollectionLike()) {
291285

@@ -299,11 +293,10 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
299293
String referenceKey = fromBytes(entry.getValue(), String.class);
300294
String[] args = referenceKey.split(":");
301295

302-
Object loadedObject = referenceResolver.resolveReference(args[1], args[0], association.getInverse()
303-
.getActualType());
296+
Map<byte[], byte[]> rawHash = referenceResolver.resolveReference(args[1], args[0]);
304297

305-
if (loadedObject != null) {
306-
target.add(loadedObject);
298+
if (!CollectionUtils.isEmpty(rawHash)) {
299+
target.add(read(association.getInverse().getActualType(), new RedisData(rawHash)));
307300
}
308301
}
309302

@@ -319,11 +312,12 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
319312
String key = fromBytes(binKey, String.class);
320313

321314
String[] args = key.split(":");
322-
Object loadedObject = referenceResolver.resolveReference(args[1], args[0], association.getInverse()
323-
.getActualType());
324315

325-
if (loadedObject != null) {
326-
accessor.setProperty(association.getInverse(), loadedObject);
316+
Map<byte[], byte[]> rawHash = referenceResolver.resolveReference(args[1], args[0]);
317+
318+
if (!CollectionUtils.isEmpty(rawHash)) {
319+
accessor.setProperty(association.getInverse(),
320+
read(association.getInverse().getActualType(), new RedisData(rawHash)));
327321
}
328322
}
329323
}
@@ -752,8 +746,8 @@ private void initializeConverters() {
752746
/**
753747
* @author Christoph Strobl
754748
*/
755-
private static class ConverterAwareParameterValueProvider implements
756-
PropertyValueProvider<KeyValuePersistentProperty> {
749+
private static class ConverterAwareParameterValueProvider
750+
implements PropertyValueProvider<KeyValuePersistentProperty> {
757751

758752
private final RedisData source;
759753
private final ConversionService conversionService;

src/main/java/org/springframework/data/redis/core/convert/ReferenceResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.redis.core.convert;
1717

1818
import java.io.Serializable;
19+
import java.util.Map;
1920

2021
import org.springframework.data.annotation.Reference;
2122

@@ -30,8 +31,7 @@ public interface ReferenceResolver {
3031
/**
3132
* @param id must not be {@literal null}.
3233
* @param keyspace must not be {@literal null}.
33-
* @param type must not be {@literal null}.
3434
* @return {@literal null} if referenced object does not exist.
3535
*/
36-
<T> T resolveReference(Serializable id, String keyspace, Class<T> type);
36+
Map<byte[], byte[]> resolveReference(Serializable id, String keyspace);
3737
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.redis.core.convert;
17+
18+
import java.io.Serializable;
19+
import java.util.Map;
20+
21+
import org.springframework.dao.DataAccessException;
22+
import org.springframework.data.redis.connection.RedisConnection;
23+
import org.springframework.data.redis.core.RedisCallback;
24+
import org.springframework.data.redis.core.RedisKeyValueAdapter;
25+
import org.springframework.data.redis.core.RedisOperations;
26+
import org.springframework.data.redis.core.convert.BinaryConverters.StringToBytesConverter;
27+
import org.springframework.util.Assert;
28+
29+
/**
30+
* {@link ReferenceResolver} using {@link RedisKeyValueAdapter} to read raw data.
31+
*
32+
* @author Christoph Strobl
33+
* @since 1.7
34+
*/
35+
public class ReferenceResolverImpl implements ReferenceResolver {
36+
37+
private final RedisOperations<?, ?> redisOps;
38+
private final StringToBytesConverter converter;
39+
40+
/**
41+
* @param redisOperations must not be {@literal null}.
42+
*/
43+
public ReferenceResolverImpl(RedisOperations<?, ?> redisOperations) {
44+
45+
Assert.notNull(redisOperations);
46+
47+
this.redisOps = redisOperations;
48+
this.converter = new StringToBytesConverter();
49+
}
50+
51+
/*
52+
* (non-Javadoc)
53+
* @see org.springframework.data.redis.core.convert.ReferenceResolver#resolveReference(java.io.Serializable, java.io.Serializable, java.lang.Class)
54+
*/
55+
@Override
56+
public Map<byte[], byte[]> resolveReference(Serializable id, String keyspace) {
57+
58+
final byte[] key = converter.convert(keyspace + ":" + id);
59+
60+
return redisOps.execute(new RedisCallback<Map<byte[], byte[]>>() {
61+
62+
@Override
63+
public Map<byte[], byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
64+
return connection.hGetAll(key);
65+
}
66+
});
67+
}
68+
}

src/main/java/org/springframework/data/redis/repository/configuration/RedisRepositoryConfigurationExtension.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,20 @@ protected String getDefaultKeyValueTemplateRef() {
8484
@Override
8585
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {
8686

87+
String redisTemplateRef = configurationSource.getAttribute("redisTemplateRef");
88+
8789
RootBeanDefinition mappingContextDefinition = createRedisMappingContext(configurationSource);
8890
mappingContextDefinition.setSource(configurationSource.getSource());
8991

9092
registerIfNotAlreadyRegistered(mappingContextDefinition, registry, MAPPING_CONTEXT_BEAN_NAME, configurationSource);
9193

9294
// register coustom conversions
9395
RootBeanDefinition customConversions = new RootBeanDefinition(CustomConversions.class);
94-
registerIfNotAlreadyRegistered(customConversions, registry, REDIS_CUSTOM_CONVERSIONS_BEAN_NAME, configurationSource);
96+
registerIfNotAlreadyRegistered(customConversions, registry, REDIS_CUSTOM_CONVERSIONS_BEAN_NAME,
97+
configurationSource);
9598

9699
// Register referenceResolver
97-
RootBeanDefinition redisReferenceResolver = createRedisReferenceResolverDefinition();
100+
RootBeanDefinition redisReferenceResolver = createRedisReferenceResolverDefinition(redisTemplateRef);
98101
redisReferenceResolver.setSource(configurationSource.getSource());
99102
registerIfNotAlreadyRegistered(redisReferenceResolver, registry, REDIS_REFERENCE_RESOLVER_BEAN_NAME,
100103
configurationSource);
@@ -109,16 +112,14 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf
109112
RootBeanDefinition redisKeyValueAdapterDefinition = new RootBeanDefinition(RedisKeyValueAdapter.class);
110113

111114
ConstructorArgumentValues constructorArgumentValuesForRedisKeyValueAdapter = new ConstructorArgumentValues();
112-
113-
String redisTemplateRef = configurationSource.getAttribute("redisTemplateRef");
114115
if (StringUtils.hasText(redisTemplateRef)) {
115116

116-
constructorArgumentValuesForRedisKeyValueAdapter.addIndexedArgumentValue(0, new RuntimeBeanReference(
117-
redisTemplateRef));
117+
constructorArgumentValuesForRedisKeyValueAdapter.addIndexedArgumentValue(0,
118+
new RuntimeBeanReference(redisTemplateRef));
118119
}
119120

120-
constructorArgumentValuesForRedisKeyValueAdapter.addIndexedArgumentValue(1, new RuntimeBeanReference(
121-
REDIS_CONVERTER_BEAN_NAME));
121+
constructorArgumentValuesForRedisKeyValueAdapter.addIndexedArgumentValue(1,
122+
new RuntimeBeanReference(REDIS_CONVERTER_BEAN_NAME));
122123

123124
redisKeyValueAdapterDefinition.setConstructorArgumentValues(constructorArgumentValuesForRedisKeyValueAdapter);
124125
registerIfNotAlreadyRegistered(redisKeyValueAdapterDefinition, registry, REDIS_ADAPTER_BEAN_NAME,
@@ -127,14 +128,15 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf
127128
super.registerBeansForRoot(registry, configurationSource);
128129
}
129130

130-
private RootBeanDefinition createRedisReferenceResolverDefinition() {
131+
private RootBeanDefinition createRedisReferenceResolverDefinition(String redisTemplateRef) {
131132

132133
RootBeanDefinition beanDef = new RootBeanDefinition();
133-
beanDef.setBeanClassName("org.springframework.data.redis.core.RedisKeyValueAdapter.ReferenceResolverImpl");
134+
beanDef.setBeanClassName("org.springframework.data.redis.core.convert.ReferenceResolverImpl");
134135

135-
MutablePropertyValues props = new MutablePropertyValues();
136-
props.add("adapter", new RuntimeBeanReference(REDIS_ADAPTER_BEAN_NAME));
137-
beanDef.setPropertyValues(props);
136+
ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues();
137+
constructorArgs.addIndexedArgumentValue(0, new RuntimeBeanReference(redisTemplateRef));
138+
139+
beanDef.setConstructorArgumentValues(constructorArgs);
138140

139141
return beanDef;
140142
}
@@ -183,10 +185,10 @@ protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition(
183185
RootBeanDefinition keyValueTemplateDefinition = new RootBeanDefinition(RedisKeyValueTemplate.class);
184186

185187
ConstructorArgumentValues constructorArgumentValuesForKeyValueTemplate = new ConstructorArgumentValues();
186-
constructorArgumentValuesForKeyValueTemplate.addIndexedArgumentValue(0, new RuntimeBeanReference(
187-
REDIS_ADAPTER_BEAN_NAME));
188-
constructorArgumentValuesForKeyValueTemplate.addIndexedArgumentValue(1, new RuntimeBeanReference(
189-
MAPPING_CONTEXT_BEAN_NAME));
188+
constructorArgumentValuesForKeyValueTemplate.addIndexedArgumentValue(0,
189+
new RuntimeBeanReference(REDIS_ADAPTER_BEAN_NAME));
190+
constructorArgumentValuesForKeyValueTemplate.addIndexedArgumentValue(1,
191+
new RuntimeBeanReference(MAPPING_CONTEXT_BEAN_NAME));
190192

191193
keyValueTemplateDefinition.setConstructorArgumentValues(constructorArgumentValuesForKeyValueTemplate);
192194

0 commit comments

Comments
 (0)