DATAREDIS-595 - Integrate DATACMNS Java 8 upgrade.
Integrate DATACMNS-867 and DATAKV-159 branches.
This commit is contained in:
@@ -23,6 +23,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -58,6 +59,7 @@ import org.springframework.data.redis.core.convert.RedisData;
|
||||
import org.springframework.data.redis.core.convert.ReferenceResolverImpl;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentProperty;
|
||||
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.data.redis.util.ByteUtils;
|
||||
@@ -204,10 +206,10 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
rdo.setId(converter.getConversionService().convert(id, String.class));
|
||||
|
||||
if (!(item instanceof RedisData)) {
|
||||
KeyValuePersistentProperty idProperty = converter.getMappingContext().getPersistentEntity(item.getClass())
|
||||
.getIdProperty();
|
||||
converter.getMappingContext().getPersistentEntity(item.getClass()).getPropertyAccessor(item)
|
||||
.setProperty(idProperty, id);
|
||||
KeyValuePersistentProperty idProperty = converter.getMappingContext().getPersistentEntity(item.getClass()).get()
|
||||
.getIdProperty().get();
|
||||
converter.getMappingContext().getPersistentEntity(item.getClass()).get().getPropertyAccessor(item)
|
||||
.setProperty(idProperty, Optional.ofNullable(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +352,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
return getAllOf(keyspace, -1, -1);
|
||||
}
|
||||
|
||||
public List<?> getAllOf(final Serializable keyspace, int offset, int rows) {
|
||||
public List<?> getAllOf(final Serializable keyspace, long offset, int rows) {
|
||||
|
||||
final byte[] binKeyspace = toBytes(keyspace);
|
||||
|
||||
@@ -372,7 +374,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
offset = Math.max(0, offset);
|
||||
if (offset >= 0 && rows > 0) {
|
||||
keys = keys.subList(offset, Math.min(offset + rows, keys.size()));
|
||||
keys = keys.subList((int)offset, Math.min((int)offset + rows, keys.size()));
|
||||
}
|
||||
|
||||
for (byte[] key : keys) {
|
||||
@@ -426,7 +428,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
public void update(final PartialUpdate<?> update) {
|
||||
|
||||
final RedisPersistentEntity<?> entity = this.converter.getMappingContext().getPersistentEntity(update.getTarget());
|
||||
final RedisPersistentEntity<?> entity = this.converter.getMappingContext().getPersistentEntity(update.getTarget()).get();
|
||||
|
||||
final String keyspace = entity.getKeySpace();
|
||||
final Object id = update.getId();
|
||||
@@ -616,29 +618,33 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
return target;
|
||||
}
|
||||
|
||||
RedisPersistentEntity<?> entity = this.converter.getMappingContext().getPersistentEntity(target.getClass());
|
||||
RedisPersistentEntity<?> entity = this.converter.getMappingContext().getPersistentEntity(target.getClass()).get();
|
||||
if (entity.hasExplictTimeToLiveProperty()) {
|
||||
|
||||
PersistentProperty<?> ttlProperty = entity.getExplicitTimeToLiveProperty();
|
||||
Optional<RedisPersistentProperty> ttlProperty = entity.getExplicitTimeToLiveProperty();
|
||||
if(!ttlProperty.isPresent()) {
|
||||
return target;
|
||||
}
|
||||
|
||||
final TimeToLive ttl = ttlProperty.findAnnotation(TimeToLive.class);
|
||||
|
||||
final Optional<TimeToLive> ttl = ttlProperty.get().findAnnotation(TimeToLive.class);
|
||||
|
||||
Long timeout = redisOps.execute(new RedisCallback<Long>() {
|
||||
|
||||
@Override
|
||||
public Long doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
|
||||
if (ObjectUtils.nullSafeEquals(TimeUnit.SECONDS, ttl.unit())) {
|
||||
if (ObjectUtils.nullSafeEquals(TimeUnit.SECONDS, ttl.get().unit())) {
|
||||
return connection.ttl(key);
|
||||
}
|
||||
|
||||
return connection.pTtl(key, ttl.unit());
|
||||
return connection.pTtl(key, ttl.get().unit());
|
||||
}
|
||||
});
|
||||
|
||||
if (timeout != null || !ttlProperty.getType().isPrimitive()) {
|
||||
entity.getPropertyAccessor(target).setProperty(ttlProperty,
|
||||
converter.getConversionService().convert(timeout, ttlProperty.getType()));
|
||||
if (timeout != null || !ttlProperty.get().getType().isPrimitive()) {
|
||||
entity.getPropertyAccessor(target).setProperty(ttlProperty.get(),
|
||||
Optional.ofNullable(converter.getConversionService().convert(timeout, ttlProperty.get().getType())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.keyvalue.core.KeyValueAdapter;
|
||||
import org.springframework.data.keyvalue.core.KeyValueCallback;
|
||||
@@ -100,9 +101,9 @@ public class RedisKeyValueTemplate extends KeyValueTemplate {
|
||||
String idToUse = adapter.getConverter().getConversionService().canConvert(id.getClass(), String.class)
|
||||
? adapter.getConverter().getConversionService().convert(id, String.class) : id.toString();
|
||||
|
||||
T candidate = findById(idToUse, type);
|
||||
if (candidate != null) {
|
||||
result.add(candidate);
|
||||
Optional<T> candidate = findById(idToUse, type);
|
||||
if (candidate.isPresent()) {
|
||||
result.add(candidate.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Collection<T> execute(final RedisOperationChain criteria, final Comparator<?> sort, final int offset,
|
||||
public <T> Collection<T> execute(final RedisOperationChain criteria, final Comparator<?> sort, final long offset,
|
||||
final int rows, final Serializable keyspace, Class<T> type) {
|
||||
|
||||
if (criteria == null
|
||||
@@ -116,7 +116,7 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
int offsetToUse = Math.max(0, offset);
|
||||
int offsetToUse = Math.max(0, (int) offset);
|
||||
if (rows > 0) {
|
||||
allKeys = allKeys.subList(Math.max(0, offsetToUse), Math.min(offsetToUse + rows, allKeys.size()));
|
||||
}
|
||||
@@ -154,7 +154,7 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
|
||||
* @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public Collection<?> execute(final RedisOperationChain criteria, Comparator<?> sort, int offset, int rows,
|
||||
public Collection<?> execute(final RedisOperationChain criteria, Comparator<?> sort, long offset, int rows,
|
||||
final Serializable keyspace) {
|
||||
return execute(criteria, sort, offset, rows, keyspace, Object.class);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -36,14 +38,13 @@ import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.CacheValue;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Value object to capture custom conversion. That is essentially a {@link List} of converters and some additional logic
|
||||
* around them.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Olivyer Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
@@ -61,9 +62,9 @@ public class CustomConversions {
|
||||
|
||||
private final List<Object> converters;
|
||||
|
||||
private final Map<ConvertiblePair, CacheValue<Class<?>>> customReadTargetTypes;
|
||||
private final Map<ConvertiblePair, CacheValue<Class<?>>> customWriteTargetTypes;
|
||||
private final Map<Class<?>, CacheValue<Class<?>>> rawWriteTargetTypes;
|
||||
private final Map<ConvertiblePair, Optional<Class<?>>> customReadTargetTypes;
|
||||
private final Map<ConvertiblePair, Optional<Class<?>>> customWriteTargetTypes;
|
||||
private final Map<Class<?>, Optional<Class<?>>> rawWriteTargetTypes;
|
||||
|
||||
/**
|
||||
* Creates an empty {@link CustomConversions} object.
|
||||
@@ -84,9 +85,9 @@ public class CustomConversions {
|
||||
this.readingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.writingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.customSimpleTypes = new HashSet<Class<?>>();
|
||||
this.customReadTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
|
||||
this.customWriteTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
|
||||
this.rawWriteTargetTypes = new ConcurrentHashMap<Class<?>, CacheValue<Class<?>>>();
|
||||
this.customReadTargetTypes = new ConcurrentHashMap<ConvertiblePair, Optional<Class<?>>>();
|
||||
this.customWriteTargetTypes = new ConcurrentHashMap<ConvertiblePair, Optional<Class<?>>>();
|
||||
this.rawWriteTargetTypes = new ConcurrentHashMap<Class<?>, Optional<Class<?>>>();
|
||||
|
||||
List<Object> toRegister = new ArrayList<Object>();
|
||||
|
||||
@@ -204,7 +205,7 @@ public class CustomConversions {
|
||||
* Registers the given {@link ConvertiblePair} as reading or writing pair depending on the type sides being basic
|
||||
* Redis types.
|
||||
*
|
||||
* @param pair
|
||||
* @param converterRegistration
|
||||
*/
|
||||
private void register(ConverterRegistration converterRegistration) {
|
||||
|
||||
@@ -239,13 +240,8 @@ public class CustomConversions {
|
||||
*/
|
||||
public Class<?> getCustomWriteTarget(final Class<?> sourceType) {
|
||||
|
||||
return getOrCreateAndCache(sourceType, rawWriteTargetTypes, new Producer() {
|
||||
|
||||
@Override
|
||||
public Class<?> get() {
|
||||
return getCustomTarget(sourceType, null, writingPairs);
|
||||
}
|
||||
});
|
||||
return getOrCreateAndCache(sourceType, rawWriteTargetTypes,
|
||||
() -> getCustomTarget(sourceType, null, writingPairs).isPresent() ? (Class) getCustomTarget(sourceType, null, writingPairs).get() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,13 +260,7 @@ public class CustomConversions {
|
||||
}
|
||||
|
||||
return getOrCreateAndCache(new ConvertiblePair(sourceType, requestedTargetType), customWriteTargetTypes,
|
||||
new Producer() {
|
||||
|
||||
@Override
|
||||
public Class<?> get() {
|
||||
return getCustomTarget(sourceType, requestedTargetType, writingPairs);
|
||||
}
|
||||
});
|
||||
() -> (Class) getCustomTarget(sourceType, requestedTargetType, writingPairs).get());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,13 +313,7 @@ public class CustomConversions {
|
||||
}
|
||||
|
||||
return getOrCreateAndCache(new ConvertiblePair(sourceType, requestedTargetType), customReadTargetTypes,
|
||||
new Producer() {
|
||||
|
||||
@Override
|
||||
public Class<?> get() {
|
||||
return getCustomTarget(sourceType, requestedTargetType, readingPairs);
|
||||
}
|
||||
});
|
||||
() -> getCustomTarget(sourceType, requestedTargetType, readingPairs).isPresent() ? ((Class) getCustomTarget(sourceType, requestedTargetType, readingPairs).get()) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,54 +325,41 @@ public class CustomConversions {
|
||||
* @param pairs must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static Class<?> getCustomTarget(Class<?> sourceType, Class<?> requestedTargetType,
|
||||
private static Optional<Class<?>> getCustomTarget(Class<?> sourceType, Class<?> requestedTargetType,
|
||||
Collection<ConvertiblePair> pairs) {
|
||||
|
||||
Assert.notNull(sourceType, "SourceType must not be null!");
|
||||
Assert.notNull(pairs, "Convertible pairs must not be null!");
|
||||
|
||||
if (requestedTargetType != null && pairs.contains(new ConvertiblePair(sourceType, requestedTargetType))) {
|
||||
return requestedTargetType;
|
||||
return Optional.of(requestedTargetType);
|
||||
}
|
||||
|
||||
for (ConvertiblePair typePair : pairs) {
|
||||
if (typePair.getSourceType().isAssignableFrom(sourceType)) {
|
||||
Class<?> targetType = typePair.getTargetType();
|
||||
if (requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) {
|
||||
return targetType;
|
||||
return Optional.of(targetType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will try to find a value for the given key in the given cache or produce one using the given {@link Producer} and
|
||||
* Will try to find a value for the given key in the given cache or produce one using the given {@link Supplier} and
|
||||
* store it in the cache.
|
||||
*
|
||||
* @param key the key to lookup a potentially existing value, must not be {@literal null}.
|
||||
* @param cache the cache to find the value in, must not be {@literal null}.
|
||||
* @param producer the {@link Producer} to create values to cache, must not be {@literal null}.
|
||||
* @param producer the {@link Supplier} to create values to cache, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static <T> Class<?> getOrCreateAndCache(T key, Map<T, CacheValue<Class<?>>> cache, Producer producer) {
|
||||
|
||||
CacheValue<Class<?>> cacheValue = cache.get(key);
|
||||
|
||||
if (cacheValue != null) {
|
||||
return cacheValue.getValue();
|
||||
}
|
||||
|
||||
Class<?> type = producer.get();
|
||||
cache.put(key, CacheValue.<Class<?>> ofNullable(type));
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private interface Producer {
|
||||
|
||||
Class<?> get();
|
||||
private static <T> Class<?> getOrCreateAndCache(T key, Map<T, Optional<Class<?>>> cache,
|
||||
Supplier<Class<T>> producer) {
|
||||
Optional<Class<?>> foo = cache.computeIfAbsent(key, t -> Optional.ofNullable(producer.get()));
|
||||
return foo.isPresent() ? foo.get() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -407,7 +378,7 @@ public class CustomConversions {
|
||||
*
|
||||
* @param convertiblePair must not be {@literal null}.
|
||||
* @param isReading whether to force to consider the converter for reading.
|
||||
* @param isWritingwhether to force to consider the converter for reading.
|
||||
* @param isWriting whether to force to consider the converter for reading.
|
||||
*/
|
||||
public ConverterRegistration(ConvertiblePair convertiblePair, boolean isReading, boolean isWriting) {
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -41,8 +42,7 @@ import org.springframework.data.convert.EntityInstantiators;
|
||||
import org.springframework.data.convert.TypeAliasAccessor;
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.Alias;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
@@ -58,6 +58,7 @@ import org.springframework.data.redis.core.PartialUpdate.UpdateCommand;
|
||||
import org.springframework.data.redis.core.index.Indexed;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentProperty;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -176,11 +177,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<?> readType = typeMapper.readType(source);
|
||||
TypeInformation<?> typeToUse = readType != null ? readType : ClassTypeInformation.from(type);
|
||||
final RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(typeToUse);
|
||||
TypeInformation<?> readType = typeMapper.readType(source).orElse(ClassTypeInformation.from(type));
|
||||
final Optional<RedisPersistentEntity<?>> entity = mappingContext.getPersistentEntity(readType);
|
||||
|
||||
if (customConversions.hasCustomReadTarget(Map.class, typeToUse.getType())) {
|
||||
if (customConversions.hasCustomReadTarget(Map.class, readType.getType())) {
|
||||
|
||||
Map<String, byte[]> partial = new HashMap<String, byte[]>();
|
||||
|
||||
@@ -193,35 +193,37 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
} else {
|
||||
partial.putAll(source.getBucket().asMap());
|
||||
}
|
||||
R instance = (R) conversionService.convert(partial, typeToUse.getType());
|
||||
R instance = (R) conversionService.convert(partial, readType.getType());
|
||||
|
||||
if (entity.hasIdProperty()) {
|
||||
entity.getPropertyAccessor(instance).setProperty(entity.getIdProperty(), source.getId());
|
||||
if (entity.isPresent() && entity.get().hasIdProperty()) {
|
||||
entity.get().getPropertyAccessor(instance).setProperty(entity.get().getIdProperty().get(),
|
||||
Optional.ofNullable(source.getId()));
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (conversionService.canConvert(byte[].class, typeToUse.getType())) {
|
||||
if (conversionService.canConvert(byte[].class, readType.getType())) {
|
||||
return (R) conversionService.convert(source.getBucket().get(StringUtils.hasText(path) ? path : "_raw"),
|
||||
typeToUse.getType());
|
||||
readType.getType());
|
||||
}
|
||||
|
||||
EntityInstantiator instantiator = entityInstantiators.getInstantiatorFor(entity);
|
||||
EntityInstantiator instantiator = entityInstantiators.getInstantiatorFor(entity.get());
|
||||
|
||||
Object instance = instantiator.createInstance((RedisPersistentEntity<?>) entity,
|
||||
new PersistentEntityParameterValueProvider<KeyValuePersistentProperty>(entity,
|
||||
new ConverterAwareParameterValueProvider(path, source, conversionService), this.conversionService));
|
||||
Object instance = instantiator.createInstance((RedisPersistentEntity<RedisPersistentProperty>) entity.get(),
|
||||
new PersistentEntityParameterValueProvider<RedisPersistentProperty>(entity.get(),
|
||||
new ConverterAwareParameterValueProvider(path, source, conversionService),
|
||||
Optional.of(this.conversionService)));
|
||||
|
||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
||||
final PersistentPropertyAccessor accessor = entity.get().getPropertyAccessor(instance);
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<KeyValuePersistentProperty>() {
|
||||
entity.get().doWithProperties(new PropertyHandler<RedisPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(KeyValuePersistentProperty persistentProperty) {
|
||||
public void doWithPersistentProperty(RedisPersistentProperty persistentProperty) {
|
||||
|
||||
String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName();
|
||||
|
||||
PreferredConstructor<?, KeyValuePersistentProperty> constructor = entity.getPersistenceConstructor();
|
||||
PreferredConstructor<?, RedisPersistentProperty> constructor = entity.get().getPersistenceConstructor().get();
|
||||
|
||||
if (constructor.isConstructorParameter(persistentProperty)) {
|
||||
return;
|
||||
@@ -240,22 +242,23 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
}
|
||||
|
||||
if (targetValue != null) {
|
||||
accessor.setProperty(persistentProperty, targetValue);
|
||||
accessor.setProperty(persistentProperty, Optional.ofNullable(targetValue));
|
||||
}
|
||||
}
|
||||
|
||||
else if (persistentProperty.isCollectionLike()) {
|
||||
|
||||
Object targetValue = readCollectionOrArray(currentPath, persistentProperty.getType(),
|
||||
persistentProperty.getTypeInformation().getComponentType().getActualType().getType(), source.getBucket());
|
||||
persistentProperty.getTypeInformation().getComponentType().get().getActualType().getType(),
|
||||
source.getBucket());
|
||||
if (targetValue != null) {
|
||||
accessor.setProperty(persistentProperty, targetValue);
|
||||
accessor.setProperty(persistentProperty, Optional.ofNullable(targetValue));
|
||||
}
|
||||
|
||||
} else if (persistentProperty.isEntity() && !conversionService.canConvert(byte[].class,
|
||||
persistentProperty.getTypeInformation().getActualType().getType())) {
|
||||
|
||||
Class<?> targetType = persistentProperty.getTypeInformation().getActualType().getType();
|
||||
Class<R> targetType = (Class<R>) persistentProperty.getTypeInformation().getActualType().getType();
|
||||
|
||||
Bucket bucket = source.getBucket().extract(currentPath + ".");
|
||||
|
||||
@@ -266,38 +269,41 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
newBucket.getBucket().put(TYPE_HINT_ALIAS, type);
|
||||
}
|
||||
|
||||
accessor.setProperty(persistentProperty, readInternal(currentPath, targetType, newBucket));
|
||||
R val = readInternal(currentPath, targetType, newBucket);
|
||||
|
||||
accessor.setProperty(persistentProperty, Optional.ofNullable(val));
|
||||
} else {
|
||||
|
||||
if (persistentProperty.isIdProperty() && StringUtils.isEmpty(path.isEmpty())) {
|
||||
|
||||
if (source.getBucket().get(currentPath) == null) {
|
||||
accessor.setProperty(persistentProperty,
|
||||
fromBytes(source.getBucket().get(currentPath), persistentProperty.getActualType()));
|
||||
Optional.of(fromBytes(source.getBucket().get(currentPath), persistentProperty.getActualType())));
|
||||
} else {
|
||||
accessor.setProperty(persistentProperty, source.getId());
|
||||
accessor.setProperty(persistentProperty, Optional.ofNullable(source.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> typeToUse = getTypeHint(currentPath, source.getBucket(), persistentProperty.getActualType());
|
||||
accessor.setProperty(persistentProperty, fromBytes(source.getBucket().get(currentPath), typeToUse));
|
||||
accessor.setProperty(persistentProperty,
|
||||
Optional.ofNullable(fromBytes(source.getBucket().get(currentPath), typeToUse)));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
readAssociation(path, source, entity, accessor);
|
||||
readAssociation(path, source, entity.get(), accessor);
|
||||
|
||||
return (R) instance;
|
||||
}
|
||||
|
||||
private void readAssociation(final String path, final RedisData source, final KeyValuePersistentEntity<?> entity,
|
||||
private void readAssociation(final String path, final RedisData source, final RedisPersistentEntity<?> entity,
|
||||
final PersistentPropertyAccessor accessor) {
|
||||
|
||||
entity.doWithAssociations(new AssociationHandler<KeyValuePersistentProperty>() {
|
||||
entity.doWithAssociations(new AssociationHandler<RedisPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithAssociation(Association<KeyValuePersistentProperty> association) {
|
||||
public void doWithAssociation(Association<RedisPersistentProperty> association) {
|
||||
|
||||
String currentPath = !path.isEmpty() ? path + "." + association.getInverse().getName()
|
||||
: association.getInverse().getName();
|
||||
@@ -321,7 +327,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
}
|
||||
}
|
||||
|
||||
accessor.setProperty(association.getInverse(), target);
|
||||
accessor.setProperty(association.getInverse(), Optional.ofNullable(target));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -338,7 +344,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
if (!CollectionUtils.isEmpty(rawHash)) {
|
||||
accessor.setProperty(association.getInverse(),
|
||||
read(association.getInverse().getActualType(), new RedisData(rawHash)));
|
||||
Optional.ofNullable(read(association.getInverse().getActualType(), new RedisData(rawHash))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,37 +368,42 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return;
|
||||
}
|
||||
|
||||
final RedisPersistentEntity entity = mappingContext.getPersistentEntity(source.getClass());
|
||||
final Optional<RedisPersistentEntity<?>> entity = mappingContext.getPersistentEntity(source.getClass());
|
||||
|
||||
if (!customConversions.hasCustomWriteTarget(source.getClass())) {
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink);
|
||||
}
|
||||
|
||||
if (entity == null) {
|
||||
if (!entity.isPresent()) {
|
||||
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink);
|
||||
sink.getBucket().put("_raw", conversionService.convert(source, byte[].class));
|
||||
return;
|
||||
}
|
||||
|
||||
sink.setKeyspace(entity.getKeySpace());
|
||||
sink.setKeyspace(entity.get().getKeySpace());
|
||||
|
||||
writeInternal(entity.getKeySpace(), "", source, entity.getTypeInformation(), sink);
|
||||
sink.setId(getConversionService().convert(entity.getIdentifierAccessor(source).getIdentifier(), String.class));
|
||||
writeInternal(entity.get().getKeySpace(), "", source, entity.get().getTypeInformation(), sink);
|
||||
|
||||
Long ttl = entity.getTimeToLiveAccessor().getTimeToLive(source);
|
||||
Optional<Object> identifyer = entity.get().getIdentifierAccessor(source).getIdentifier();
|
||||
|
||||
if (identifyer.isPresent()) {
|
||||
sink.setId(getConversionService().convert(identifyer.get(), String.class));
|
||||
}
|
||||
|
||||
Long ttl = entity.get().getTimeToLiveAccessor().getTimeToLive(source);
|
||||
if (ttl != null && ttl > 0) {
|
||||
sink.setTimeToLive(ttl);
|
||||
}
|
||||
|
||||
for (IndexedData indexedData : indexResolver.resolveIndexesFor(entity.getTypeInformation(), source)) {
|
||||
for (IndexedData indexedData : indexResolver.resolveIndexesFor(entity.get().getTypeInformation(), source)) {
|
||||
sink.addIndexedData(indexedData);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writePartialUpdate(PartialUpdate<?> update, RedisData sink) {
|
||||
|
||||
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(update.getTarget());
|
||||
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(update.getTarget()).get();
|
||||
|
||||
write(update.getValue(), sink);
|
||||
if (sink.getBucket().keySet().contains(TYPE_HINT_ALIAS)) {
|
||||
@@ -427,7 +438,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
private void writePartialPropertyUpdate(PartialUpdate<?> update, PropertyUpdate pUpdate, RedisData sink,
|
||||
RedisPersistentEntity<?> entity, String path) {
|
||||
|
||||
KeyValuePersistentProperty targetProperty = getTargetPropertyOrNullForPath(path, update.getTarget());
|
||||
RedisPersistentProperty targetProperty = getTargetPropertyOrNullForPath(path, update.getTarget());
|
||||
|
||||
if (targetProperty == null) {
|
||||
|
||||
@@ -436,7 +447,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
TypeInformation<?> ti = targetProperty == null ? ClassTypeInformation.OBJECT
|
||||
: (targetProperty.isMap()
|
||||
? (targetProperty.getTypeInformation().getMapValueType() != null
|
||||
? targetProperty.getTypeInformation().getMapValueType() : ClassTypeInformation.OBJECT)
|
||||
? targetProperty.getTypeInformation().getMapValueType().get() : ClassTypeInformation.OBJECT)
|
||||
: targetProperty.getTypeInformation().getActualType());
|
||||
|
||||
writeInternal(entity.getKeySpace(), pUpdate.getPropertyPath(), pUpdate.getValue(), ti, sink);
|
||||
@@ -447,23 +458,28 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
if (targetProperty.isCollectionLike()) {
|
||||
|
||||
KeyValuePersistentEntity<?> ref = mappingContext.getPersistentEntity(
|
||||
targetProperty.getAssociation().getInverse().getTypeInformation().getComponentType().getActualType());
|
||||
RedisPersistentEntity<?> ref = mappingContext.getPersistentEntity(targetProperty.getAssociation().get()
|
||||
.getInverse().getTypeInformation().getComponentType().get().getActualType()).get();
|
||||
|
||||
int i = 0;
|
||||
for (Object o : (Collection<?>) pUpdate.getValue()) {
|
||||
|
||||
Object refId = ref.getPropertyAccessor(o).getProperty(ref.getIdProperty());
|
||||
sink.getBucket().put(pUpdate.getPropertyPath() + ".[" + i + "]", toBytes(ref.getKeySpace() + ":" + refId));
|
||||
i++;
|
||||
Optional<Object> refId = ref.getPropertyAccessor(o).getProperty(ref.getIdProperty().get());
|
||||
if (refId.isPresent()) {
|
||||
sink.getBucket().put(pUpdate.getPropertyPath() + ".[" + i + "]",
|
||||
toBytes(ref.getKeySpace() + ":" + refId.get()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
KeyValuePersistentEntity<?> ref = mappingContext
|
||||
.getPersistentEntity(targetProperty.getAssociation().getInverse().getTypeInformation());
|
||||
RedisPersistentEntity<?> ref = mappingContext
|
||||
.getPersistentEntity(targetProperty.getAssociation().get().getInverse().getTypeInformation()).get();
|
||||
|
||||
Object refId = ref.getPropertyAccessor(pUpdate.getValue()).getProperty(ref.getIdProperty());
|
||||
sink.getBucket().put(pUpdate.getPropertyPath(), toBytes(ref.getKeySpace() + ":" + refId));
|
||||
Optional<Object> refId = ref.getPropertyAccessor(pUpdate.getValue()).getProperty(ref.getIdProperty().get());
|
||||
if (refId.isPresent()) {
|
||||
sink.getBucket().put(pUpdate.getPropertyPath(), toBytes(ref.getKeySpace() + ":" + refId.get()));
|
||||
}
|
||||
}
|
||||
} else if (targetProperty.isCollectionLike()) {
|
||||
|
||||
@@ -504,11 +520,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
}
|
||||
}
|
||||
|
||||
KeyValuePersistentProperty getTargetPropertyOrNullForPath(String path, Class<?> type) {
|
||||
RedisPersistentProperty getTargetPropertyOrNullForPath(String path, Class<?> type) {
|
||||
|
||||
try {
|
||||
|
||||
PersistentPropertyPath<KeyValuePersistentProperty> persistentPropertyPath = mappingContext
|
||||
PersistentPropertyPath<RedisPersistentProperty> persistentPropertyPath = mappingContext
|
||||
.getPersistentPropertyPath(path, type);
|
||||
return persistentPropertyPath.getLeafProperty();
|
||||
} catch (Exception e) {
|
||||
@@ -552,49 +568,66 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
toBytes(value.getClass().getName()));
|
||||
}
|
||||
|
||||
final KeyValuePersistentEntity<?> entity = mappingContext.getPersistentEntity(value.getClass());
|
||||
final RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(value.getClass()).get();
|
||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<KeyValuePersistentProperty>() {
|
||||
entity.doWithProperties(new PropertyHandler<RedisPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(KeyValuePersistentProperty persistentProperty) {
|
||||
public void doWithPersistentProperty(RedisPersistentProperty persistentProperty) {
|
||||
|
||||
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + persistentProperty.getName();
|
||||
|
||||
if (persistentProperty.isIdProperty()) {
|
||||
|
||||
sink.getBucket().put(propertyStringPath, toBytes(accessor.getProperty(persistentProperty)));
|
||||
if (accessor.getProperty(persistentProperty).isPresent()) {
|
||||
sink.getBucket().put(propertyStringPath, toBytes(accessor.getProperty(persistentProperty).get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (persistentProperty.isMap()) {
|
||||
writeMap(keyspace, propertyStringPath, persistentProperty.getMapValueType(),
|
||||
(Map<?, ?>) accessor.getProperty(persistentProperty), sink);
|
||||
|
||||
if (accessor.getProperty(persistentProperty).isPresent()) {
|
||||
writeMap(keyspace, propertyStringPath, persistentProperty.getMapValueType(),
|
||||
(Map<?, ?>) accessor.getProperty(persistentProperty).get(), sink);
|
||||
}
|
||||
} else if (persistentProperty.isCollectionLike()) {
|
||||
|
||||
final Object property = accessor.getProperty(persistentProperty);
|
||||
final Optional<Object> propertyValue = accessor.getProperty(persistentProperty);
|
||||
|
||||
if (property == null || Iterable.class.isAssignableFrom(property.getClass())) {
|
||||
|
||||
writeCollection(keyspace, propertyStringPath, (Iterable<?>) property,
|
||||
persistentProperty.getTypeInformation().getComponentType(), sink);
|
||||
} else if (property.getClass().isArray()) {
|
||||
|
||||
writeCollection(keyspace, propertyStringPath, CollectionUtils.arrayToList(property),
|
||||
persistentProperty.getTypeInformation().getComponentType(), sink);
|
||||
if (!propertyValue.isPresent()) {
|
||||
writeCollection(keyspace, propertyStringPath, (Iterable<?>) null,
|
||||
persistentProperty.getTypeInformation().getComponentType().get(), sink);
|
||||
} else {
|
||||
|
||||
throw new RuntimeException("Don't know how to handle " + property.getClass() + " type collection");
|
||||
if (Iterable.class.isAssignableFrom(propertyValue.get().getClass())) {
|
||||
|
||||
writeCollection(keyspace, propertyStringPath, (Iterable<?>) propertyValue.get(),
|
||||
persistentProperty.getTypeInformation().getComponentType().get(), sink);
|
||||
} else if (propertyValue.isPresent() && propertyValue.get().getClass().isArray()) {
|
||||
|
||||
writeCollection(keyspace, propertyStringPath, CollectionUtils.arrayToList(propertyValue.get()),
|
||||
persistentProperty.getTypeInformation().getComponentType().get(), sink);
|
||||
} else {
|
||||
|
||||
throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type collection");
|
||||
}
|
||||
}
|
||||
|
||||
} else if (persistentProperty.isEntity()) {
|
||||
writeInternal(keyspace, propertyStringPath, accessor.getProperty(persistentProperty),
|
||||
persistentProperty.getTypeInformation().getActualType(), sink);
|
||||
|
||||
Optional<Object> propertyValue = accessor.getProperty(persistentProperty);
|
||||
if (propertyValue.isPresent()) {
|
||||
writeInternal(keyspace, propertyStringPath, propertyValue.get(),
|
||||
persistentProperty.getTypeInformation().getActualType(), sink);
|
||||
}
|
||||
} else {
|
||||
|
||||
Object propertyValue = accessor.getProperty(persistentProperty);
|
||||
writeToBucket(propertyStringPath, propertyValue, sink, persistentProperty.getType());
|
||||
Optional<Object> propertyValue = accessor.getProperty(persistentProperty);
|
||||
if (propertyValue.isPresent()) {
|
||||
writeToBucket(propertyStringPath, propertyValue.get(), sink, persistentProperty.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -602,7 +635,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
writeAssociation(path, entity, value, sink);
|
||||
}
|
||||
|
||||
private void writeAssociation(final String path, final KeyValuePersistentEntity<?> entity, final Object value,
|
||||
private void writeAssociation(final String path, final RedisPersistentEntity<?> entity, final Object value,
|
||||
final RedisData sink) {
|
||||
|
||||
if (value == null) {
|
||||
@@ -611,42 +644,46 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
|
||||
|
||||
entity.doWithAssociations(new AssociationHandler<KeyValuePersistentProperty>() {
|
||||
entity.doWithAssociations(new AssociationHandler<RedisPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithAssociation(Association<KeyValuePersistentProperty> association) {
|
||||
public void doWithAssociation(Association<RedisPersistentProperty> association) {
|
||||
|
||||
Object refObject = accessor.getProperty(association.getInverse());
|
||||
if (refObject == null) {
|
||||
Optional<Object> refObject = accessor.getProperty(association.getInverse());
|
||||
if (!refObject.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (association.getInverse().isCollectionLike()) {
|
||||
|
||||
KeyValuePersistentEntity<?> ref = mappingContext
|
||||
.getPersistentEntity(association.getInverse().getTypeInformation().getComponentType().getActualType());
|
||||
RedisPersistentEntity<?> ref = mappingContext.getPersistentEntity(
|
||||
association.getInverse().getTypeInformation().getComponentType().get().getActualType()).get();
|
||||
|
||||
String keyspace = ref.getKeySpace();
|
||||
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
|
||||
|
||||
int i = 0;
|
||||
for (Object o : (Collection<?>) refObject) {
|
||||
for (Object o : (Collection<?>) refObject.get()) {
|
||||
|
||||
Object refId = ref.getPropertyAccessor(o).getProperty(ref.getIdProperty());
|
||||
sink.getBucket().put(propertyStringPath + ".[" + i + "]", toBytes(keyspace + ":" + refId));
|
||||
i++;
|
||||
Optional<Object> refId = ref.getPropertyAccessor(o).getProperty(ref.getIdProperty().get());
|
||||
if (refId.isPresent()) {
|
||||
sink.getBucket().put(propertyStringPath + ".[" + i + "]", toBytes(keyspace + ":" + refId.get()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
KeyValuePersistentEntity<?> ref = mappingContext
|
||||
.getPersistentEntity(association.getInverse().getTypeInformation());
|
||||
RedisPersistentEntity<?> ref = mappingContext
|
||||
.getPersistentEntity(association.getInverse().getTypeInformation()).get();
|
||||
String keyspace = ref.getKeySpace();
|
||||
|
||||
Object refId = ref.getPropertyAccessor(refObject).getProperty(ref.getIdProperty());
|
||||
Optional<Object> refId = ref.getPropertyAccessor(refObject.get()).getProperty(ref.getIdProperty().get());
|
||||
|
||||
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
|
||||
sink.getBucket().put(propertyStringPath, toBytes(keyspace + ":" + refId));
|
||||
if (refId.isPresent()) {
|
||||
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
|
||||
sink.getBucket().put(propertyStringPath, toBytes(keyspace + ":" + refId.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -691,7 +728,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
private void writeToBucket(String path, Object value, RedisData sink, Class<?> propertyType) {
|
||||
|
||||
if (value == null) {
|
||||
if (value == null || (value instanceof Optional && !((Optional<?>) value).isPresent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -989,8 +1026,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
private static class ConverterAwareParameterValueProvider
|
||||
implements PropertyValueProvider<KeyValuePersistentProperty> {
|
||||
private static class ConverterAwareParameterValueProvider implements PropertyValueProvider<RedisPersistentProperty> {
|
||||
|
||||
private final String path;
|
||||
private final RedisData source;
|
||||
@@ -1005,10 +1041,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getPropertyValue(KeyValuePersistentProperty property) {
|
||||
public <T> Optional<T> getPropertyValue(RedisPersistentProperty property) {
|
||||
|
||||
String name = StringUtils.hasText(path) ? path + "." + property.getName() : property.getName();
|
||||
return (T) conversionService.convert(source.getBucket().get(name), property.getActualType());
|
||||
return Optional.ofNullable((T) conversionService.convert(source.getBucket().get(name), property.getActualType()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1032,8 +1068,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readAliasFrom(RedisData source) {
|
||||
return conversionService.convert(source.getBucket().get(typeKey), String.class);
|
||||
public Alias readAliasFrom(RedisData source) {
|
||||
return Alias
|
||||
.ofOptional(Optional.ofNullable(conversionService.convert(source.getBucket().get(typeKey), String.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,10 +20,10 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.redis.core.index.Indexed;
|
||||
import org.springframework.data.redis.core.index.SimpleIndexDefinition;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentProperty;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -87,8 +88,8 @@ public class PathIndexResolver implements IndexResolver {
|
||||
* @see org.springframework.data.redis.core.convert.IndexResolver#resolveIndexesFor(org.springframework.data.util.TypeInformation, java.lang.Object)
|
||||
*/
|
||||
public Set<IndexedData> resolveIndexesFor(TypeInformation<?> typeInformation, Object value) {
|
||||
return doResolveIndexesFor(mappingContext.getPersistentEntity(typeInformation).getKeySpace(), "", typeInformation,
|
||||
null, value);
|
||||
return doResolveIndexesFor(mappingContext.getPersistentEntity(typeInformation).get().getKeySpace(), "",
|
||||
typeInformation, null, value);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -103,40 +104,40 @@ public class PathIndexResolver implements IndexResolver {
|
||||
private Set<IndexedData> doResolveIndexesFor(final String keyspace, final String path,
|
||||
TypeInformation<?> typeInformation, PersistentProperty<?> fallback, Object value) {
|
||||
|
||||
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(typeInformation);
|
||||
Optional<RedisPersistentEntity<?>> entity = mappingContext.getPersistentEntity(typeInformation);
|
||||
|
||||
if (entity == null || (value != null && VALUE_TYPES.contains(value.getClass()))) {
|
||||
if (!entity.isPresent() || (value != null && VALUE_TYPES.contains(value.getClass()))) {
|
||||
return resolveIndex(keyspace, path, fallback, value);
|
||||
}
|
||||
|
||||
// this might happen on update where we address a property within an entity directly
|
||||
if (!ClassUtils.isAssignable(entity.getType(), value.getClass())) {
|
||||
if (!ClassUtils.isAssignable(entity.get().getType(), value.getClass())) {
|
||||
|
||||
String propertyName = path.lastIndexOf('.') > 0 ? path.substring(path.lastIndexOf('.') + 1, path.length()) : path;
|
||||
return resolveIndex(keyspace, path, entity.getPersistentProperty(propertyName), value);
|
||||
return resolveIndex(keyspace, path, entity.get().getPersistentProperty(propertyName).get(), value);
|
||||
}
|
||||
|
||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
|
||||
final PersistentPropertyAccessor accessor = entity.get().getPropertyAccessor(value);
|
||||
final Set<IndexedData> indexes = new LinkedHashSet<IndexedData>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<KeyValuePersistentProperty>() {
|
||||
entity.get().doWithProperties(new PropertyHandler<RedisPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(KeyValuePersistentProperty persistentProperty) {
|
||||
public void doWithPersistentProperty(RedisPersistentProperty persistentProperty) {
|
||||
|
||||
String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName();
|
||||
|
||||
Object propertyValue = accessor.getProperty(persistentProperty);
|
||||
Optional<Object> propertyValue = accessor.getProperty(persistentProperty);
|
||||
|
||||
if (propertyValue != null) {
|
||||
if (propertyValue.isPresent()) {
|
||||
|
||||
TypeInformation<?> typeHint = persistentProperty.isMap()
|
||||
? persistentProperty.getTypeInformation().getMapValueType()
|
||||
? persistentProperty.getTypeInformation().getMapValueType().get()
|
||||
: persistentProperty.getTypeInformation().getActualType();
|
||||
|
||||
if (persistentProperty.isMap()) {
|
||||
|
||||
for (Entry<?, ?> entry : ((Map<?, ?>) propertyValue).entrySet()) {
|
||||
for (Entry<?, ?> entry : ((Map<?, ?>) propertyValue.get()).entrySet()) {
|
||||
|
||||
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, entry.getValue());
|
||||
indexes.addAll(doResolveIndexesFor(keyspace, currentPath + "." + entry.getKey(),
|
||||
@@ -147,13 +148,13 @@ public class PathIndexResolver implements IndexResolver {
|
||||
|
||||
final Iterable<?> iterable;
|
||||
|
||||
if (Iterable.class.isAssignableFrom(propertyValue.getClass())) {
|
||||
iterable = (Iterable<?>) propertyValue;
|
||||
} else if (propertyValue.getClass().isArray()) {
|
||||
iterable = CollectionUtils.arrayToList(propertyValue);
|
||||
if (Iterable.class.isAssignableFrom(propertyValue.get().getClass())) {
|
||||
iterable = (Iterable<?>) propertyValue.get();
|
||||
} else if (propertyValue.get().getClass().isArray()) {
|
||||
iterable = CollectionUtils.arrayToList(propertyValue.get());
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Don't know how to handle " + propertyValue.getClass() + " type of collection");
|
||||
"Don't know how to handle " + propertyValue.get().getClass() + " type of collection");
|
||||
}
|
||||
|
||||
for (Object listValue : iterable) {
|
||||
@@ -169,11 +170,11 @@ public class PathIndexResolver implements IndexResolver {
|
||||
else if (persistentProperty.isEntity()
|
||||
|| persistentProperty.getTypeInformation().getActualType().equals(ClassTypeInformation.OBJECT)) {
|
||||
|
||||
typeHint = updateTypeHintForActualValue(typeHint, propertyValue);
|
||||
typeHint = updateTypeHintForActualValue(typeHint, propertyValue.get());
|
||||
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeHint.getActualType(), persistentProperty,
|
||||
propertyValue));
|
||||
propertyValue.get()));
|
||||
} else {
|
||||
indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue));
|
||||
indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +184,7 @@ public class PathIndexResolver implements IndexResolver {
|
||||
|
||||
if (typeHint.equals(ClassTypeInformation.OBJECT) || typeHint.getClass().isInterface()) {
|
||||
try {
|
||||
typeHint = mappingContext.getPersistentEntity(propertyValue.getClass()).getTypeInformation();
|
||||
typeHint = mappingContext.getPersistentEntity(propertyValue.getClass()).get().getTypeInformation();
|
||||
} catch (Exception e) {
|
||||
// ignore for cases where property value cannot be resolved as an entity, in that case the provided type
|
||||
// hint has to be sufficient
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
package org.springframework.data.redis.core.convert;
|
||||
|
||||
import org.springframework.data.convert.EntityConverter;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentProperty;
|
||||
|
||||
/**
|
||||
* Redis specific {@link EntityConverter}.
|
||||
@@ -27,7 +27,7 @@ import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface RedisConverter
|
||||
extends EntityConverter<KeyValuePersistentEntity<?>, KeyValuePersistentProperty, Object, RedisData> {
|
||||
extends EntityConverter<RedisPersistentEntity<?>, RedisPersistentProperty, Object, RedisData> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -19,14 +19,15 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.redis.core.index.ConfigurableIndexDefinitionProvider;
|
||||
import org.springframework.data.redis.core.index.IndexDefinition;
|
||||
import org.springframework.data.redis.core.index.SpelIndexDefinition;
|
||||
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.expression.BeanResolver;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -85,13 +86,13 @@ public class SpelIndexResolver implements IndexResolver {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
KeyValuePersistentEntity<?> entity = mappingContext.getPersistentEntity(typeInformation);
|
||||
Optional<RedisPersistentEntity<?>> entity = mappingContext.getPersistentEntity(typeInformation);
|
||||
|
||||
if (entity == null) {
|
||||
if (!entity.isPresent()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
String keyspace = entity.getKeySpace();
|
||||
String keyspace = entity.get().getKeySpace();
|
||||
|
||||
Set<IndexedData> indexes = new HashSet<IndexedData>();
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.mapping;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.redis.core.TimeToLive;
|
||||
import org.springframework.data.redis.core.TimeToLiveAccessor;
|
||||
@@ -31,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
* @author Christoph Strobl
|
||||
* @param <T>
|
||||
*/
|
||||
public class BasicRedisPersistentEntity<T> extends BasicKeyValuePersistentEntity<T>
|
||||
public class BasicRedisPersistentEntity<T> extends BasicKeyValuePersistentEntity<T, RedisPersistentProperty>
|
||||
implements RedisPersistentEntity<T> {
|
||||
|
||||
private TimeToLiveAccessor timeToLiveAccessor;
|
||||
@@ -74,17 +75,16 @@ public class BasicRedisPersistentEntity<T> extends BasicKeyValuePersistentEntity
|
||||
* @see org.springframework.data.redis.core.mapping.RedisPersistentEntity#getExplicitTimeToLiveProperty()
|
||||
*/
|
||||
@Override
|
||||
public RedisPersistentProperty getExplicitTimeToLiveProperty() {
|
||||
return (RedisPersistentProperty) this.getPersistentProperty(TimeToLive.class);
|
||||
public Optional<RedisPersistentProperty> getExplicitTimeToLiveProperty() {
|
||||
return this.getPersistentProperty(TimeToLive.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.BasicPersistentEntity#returnPropertyIfBetterIdPropertyCandidateOrNull(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.BasicPersistentEntity#returnPropertyIfBetterIdPropertyCandidateOrNull(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@Override
|
||||
protected KeyValuePersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(
|
||||
KeyValuePersistentProperty property) {
|
||||
protected RedisPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(RedisPersistentProperty property) {
|
||||
|
||||
Assert.notNull(property, "Property must not be null!");
|
||||
|
||||
@@ -92,27 +92,29 @@ public class BasicRedisPersistentEntity<T> extends BasicKeyValuePersistentEntity
|
||||
return null;
|
||||
}
|
||||
|
||||
KeyValuePersistentProperty currentIdProperty = getIdProperty();
|
||||
boolean currentIdPropertyIsSet = currentIdProperty != null;
|
||||
Optional<RedisPersistentProperty> currentIdProperty = getIdProperty();
|
||||
boolean currentIdPropertyIsSet = currentIdProperty.isPresent();
|
||||
|
||||
if (!currentIdPropertyIsSet) {
|
||||
return property;
|
||||
}
|
||||
|
||||
boolean currentIdPropertyIsExplicit = currentIdProperty.isAnnotationPresent(Id.class);
|
||||
boolean currentIdPropertyIsExplicit = currentIdProperty.get().isAnnotationPresent(Id.class);
|
||||
boolean newIdPropertyIsExplicit = property.isAnnotationPresent(Id.class);
|
||||
|
||||
if (currentIdPropertyIsExplicit && newIdPropertyIsExplicit) {
|
||||
throw new MappingException(String.format(
|
||||
"Attempt to add explicit id property %s but already have an property %s registered "
|
||||
+ "as explicit id. Check your mapping configuration!",
|
||||
property.getField(), currentIdProperty.getField()));
|
||||
property.getField(), currentIdProperty.get().getField()));
|
||||
}
|
||||
|
||||
if (!currentIdPropertyIsExplicit && !newIdPropertyIsExplicit) {
|
||||
throw new MappingException(
|
||||
String.format("Attempt to add id property %s but already have an property %s registered "
|
||||
+ "as id. Check your mapping configuration!", property.getField(), currentIdProperty.getField()));
|
||||
String.format(
|
||||
"Attempt to add id property %s but already have an property %s registered "
|
||||
+ "as id. Check your mapping configuration!",
|
||||
property.getField(), currentIdProperty.get().getField()));
|
||||
}
|
||||
|
||||
if (newIdPropertyIsExplicit) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -15,22 +15,20 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.Property;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.redis.core.PartialUpdate;
|
||||
import org.springframework.data.redis.core.PartialUpdate.PropertyUpdate;
|
||||
@@ -58,7 +56,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.7
|
||||
*/
|
||||
public class RedisMappingContext extends KeyValueMappingContext {
|
||||
public class RedisMappingContext extends KeyValueMappingContext<RedisPersistentEntity<?>, RedisPersistentProperty> {
|
||||
|
||||
private final MappingConfiguration mappingConfiguration;
|
||||
private final TimeToLiveAccessor timeToLiveAccessor;
|
||||
@@ -96,50 +94,15 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
this.fallbackKeySpaceResolver = fallbackKeySpaceResolver;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> RedisPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new BasicRedisPersistentEntity<T>(typeInformation, fallbackKeySpaceResolver, timeToLiveAccessor);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#getPersistentEntity(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public RedisPersistentEntity<?> getPersistentEntity(Class<?> type) {
|
||||
return (RedisPersistentEntity<?>) super.getPersistentEntity(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#getPersistentEntity(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@Override
|
||||
public RedisPersistentEntity<?> getPersistentEntity(KeyValuePersistentProperty persistentProperty) {
|
||||
return (RedisPersistentEntity<?>) super.getPersistentEntity(persistentProperty);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#getPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
public RedisPersistentEntity<?> getPersistentEntity(TypeInformation<?> type) {
|
||||
return (RedisPersistentEntity<?>) super.getPersistentEntity(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
*/
|
||||
@Override
|
||||
protected KeyValuePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
KeyValuePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new RedisPersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
protected RedisPersistentProperty createPersistentProperty(Property property, RedisPersistentEntity<?> owner,
|
||||
SimpleTypeHolder simpleTypeHolder) {
|
||||
return new RedisPersistentProperty(property, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,8 +222,8 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
|
||||
if (ttlProperty != null) {
|
||||
|
||||
if (ttlProperty.findAnnotation(TimeToLive.class) != null) {
|
||||
unit = ttlProperty.findAnnotation(TimeToLive.class).unit();
|
||||
if (ttlProperty.findAnnotation(TimeToLive.class).isPresent()) {
|
||||
unit = ttlProperty.findAnnotation(TimeToLive.class).get().unit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,10 +244,11 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
|
||||
} else if (ttlProperty != null) {
|
||||
|
||||
RedisPersistentEntity entity = mappingContext.getPersistentEntity(type);
|
||||
Number timeout = (Number) entity.getPropertyAccessor(source).getProperty(ttlProperty);
|
||||
if (timeout != null) {
|
||||
return TimeUnit.SECONDS.convert(timeout.longValue(), unit);
|
||||
RedisPersistentEntity entity = mappingContext.getPersistentEntity(type).get();
|
||||
|
||||
Optional<Object> ttlPropertyValue = entity.getPropertyAccessor(source).getProperty(ttlProperty);
|
||||
if (ttlPropertyValue.isPresent()) {
|
||||
return TimeUnit.SECONDS.convert(((Number) ttlPropertyValue.get()).longValue(), unit);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -326,9 +290,9 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
defaultTimeout = keyspaceConfig.getKeyspaceSettings(type).getTimeToLive();
|
||||
}
|
||||
|
||||
RedisHash hash = mappingContext.getPersistentEntity(type).findAnnotation(RedisHash.class);
|
||||
if (hash != null && hash.timeToLive() > 0) {
|
||||
defaultTimeout = hash.timeToLive();
|
||||
Optional<RedisHash> hash = mappingContext.getPersistentEntity(type).get().findAnnotation(RedisHash.class);
|
||||
if (hash.isPresent() && hash.get().timeToLive() > 0) {
|
||||
defaultTimeout = hash.get().timeToLive();
|
||||
}
|
||||
|
||||
defaultTimeouts.put(type, defaultTimeout);
|
||||
@@ -342,13 +306,13 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
return timeoutProperties.get(type);
|
||||
}
|
||||
|
||||
RedisPersistentEntity entity = mappingContext.getPersistentEntity(type);
|
||||
PersistentProperty<?> ttlProperty = entity.getPersistentProperty(TimeToLive.class);
|
||||
RedisPersistentEntity entity = mappingContext.getPersistentEntity(type).get();
|
||||
Optional<PersistentProperty<?>> ttlProperty = entity.getPersistentProperty(TimeToLive.class);
|
||||
|
||||
if (ttlProperty != null) {
|
||||
if (ttlProperty.isPresent()) {
|
||||
|
||||
timeoutProperties.put(type, ttlProperty);
|
||||
return ttlProperty;
|
||||
timeoutProperties.put(type, ttlProperty.get());
|
||||
return ttlProperty.get();
|
||||
}
|
||||
|
||||
if (keyspaceConfig.hasSettingsFor(type)) {
|
||||
@@ -357,8 +321,10 @@ public class RedisMappingContext extends KeyValueMappingContext {
|
||||
if (StringUtils.hasText(settings.getTimeToLivePropertyName())) {
|
||||
|
||||
ttlProperty = entity.getPersistentProperty(settings.getTimeToLivePropertyName());
|
||||
timeoutProperties.put(type, ttlProperty);
|
||||
return ttlProperty;
|
||||
if (ttlProperty.isPresent()) {
|
||||
timeoutProperties.put(type, ttlProperty.get());
|
||||
return ttlProperty.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.mapping;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
@@ -27,7 +29,7 @@ import org.springframework.data.redis.core.TimeToLiveAccessor;
|
||||
* @param <T>
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface RedisPersistentEntity<T> extends KeyValuePersistentEntity<T> {
|
||||
public interface RedisPersistentEntity<T> extends KeyValuePersistentEntity<T, RedisPersistentProperty> {
|
||||
|
||||
/**
|
||||
* Get the {@link TimeToLiveAccessor} associated with the entity.
|
||||
@@ -48,6 +50,6 @@ public interface RedisPersistentEntity<T> extends KeyValuePersistentEntity<T> {
|
||||
* @return can be {@null}.
|
||||
* @since 1.8
|
||||
*/
|
||||
PersistentProperty<? extends PersistentProperty<?>> getExplicitTimeToLiveProperty();
|
||||
Optional<RedisPersistentProperty> getExplicitTimeToLiveProperty();
|
||||
|
||||
}
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.Property;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
|
||||
/**
|
||||
@@ -31,7 +30,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
*/
|
||||
public class RedisPersistentProperty extends KeyValuePersistentProperty {
|
||||
public class RedisPersistentProperty extends KeyValuePersistentProperty<RedisPersistentProperty> {
|
||||
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
|
||||
@@ -42,14 +41,13 @@ public class RedisPersistentProperty extends KeyValuePersistentProperty {
|
||||
/**
|
||||
* Creates new {@link RedisPersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param property
|
||||
* @param owner
|
||||
* @param simpleTypeHolder
|
||||
*/
|
||||
public RedisPersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
PersistentEntity<?, KeyValuePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
public RedisPersistentProperty(Property property, PersistentEntity<?, RedisPersistentProperty> owner,
|
||||
SimpleTypeHolder simpleTypeHolder) {
|
||||
super(property, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.redis.repository.cdi;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.enterprise.context.spi.CreationalContext;
|
||||
@@ -53,22 +54,18 @@ public class RedisRepositoryBean<T> extends CdiRepositoryBean<T> {
|
||||
public RedisRepositoryBean(Bean<KeyValueOperations> keyValueTemplate, Set<Annotation> qualifiers,
|
||||
Class<T> repositoryType, BeanManager beanManager, CustomRepositoryImplementationDetector detector) {
|
||||
|
||||
super(qualifiers, repositoryType, beanManager, detector);
|
||||
super(qualifiers, repositoryType, beanManager, Optional.ofNullable(detector));
|
||||
Assert.notNull(keyValueTemplate, "Bean holding keyvalue template must not be null!");
|
||||
this.keyValueTemplate = keyValueTemplate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Object customImplementation) {
|
||||
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType,
|
||||
Optional<Object> customImplementation) {
|
||||
|
||||
KeyValueOperations keyValueTemplate = getDependencyInstance(this.keyValueTemplate, KeyValueOperations.class);
|
||||
RedisRepositoryFactory factory = new RedisRepositoryFactory(keyValueTemplate, RedisQueryCreator.class);
|
||||
|
||||
return factory.getRepository(repositoryType, customImplementation);
|
||||
return customImplementation.isPresent() ? factory.getRepository(repositoryType, customImplementation.get()) : factory.getRepository(repositoryType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
@Override
|
||||
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {
|
||||
|
||||
String redisTemplateRef = configurationSource.getAttribute("redisTemplateRef");
|
||||
String redisTemplateRef = configurationSource.getAttribute("redisTemplateRef").get();
|
||||
|
||||
RootBeanDefinition mappingContextDefinition = createRedisMappingContext(configurationSource);
|
||||
mappingContextDefinition.setSource(configurationSource.getSource());
|
||||
|
||||
@@ -80,7 +80,7 @@ public class RedisRepositoryFactory extends KeyValueRepositoryFactory {
|
||||
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
|
||||
RedisPersistentEntity<T> entity = (RedisPersistentEntity<T>) operations.getMappingContext()
|
||||
.getPersistentEntity(domainClass);
|
||||
.getPersistentEntity(domainClass).get();
|
||||
EntityInformation<T, ID> entityInformation = (EntityInformation<T, ID>) new MappingRedisEntityInformation<T, ID>(
|
||||
entity);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user