diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java index 31742dd52..c75fb6501 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java @@ -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 ttlProperty = entity.getExplicitTimeToLiveProperty(); + if(!ttlProperty.isPresent()) { + return target; + } - final TimeToLive ttl = ttlProperty.findAnnotation(TimeToLive.class); + + final Optional ttl = ttlProperty.get().findAnnotation(TimeToLive.class); Long timeout = redisOps.execute(new RedisCallback() { @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()))); } } diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java index a914bdf07..99abd00db 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java @@ -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 candidate = findById(idToUse, type); + if (candidate.isPresent()) { + result.add(candidate.get()); } } diff --git a/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java b/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java index 684aa5a98..97ee20557 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java +++ b/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java @@ -76,7 +76,7 @@ class RedisQueryEngine extends QueryEngine Collection execute(final RedisOperationChain criteria, final Comparator sort, final int offset, + public Collection execute(final RedisOperationChain criteria, final Comparator sort, final long offset, final int rows, final Serializable keyspace, Class type) { if (criteria == null @@ -116,7 +116,7 @@ class RedisQueryEngine extends QueryEngine 0) { allKeys = allKeys.subList(Math.max(0, offsetToUse), Math.min(offsetToUse + rows, allKeys.size())); } @@ -154,7 +154,7 @@ class RedisQueryEngine extends QueryEngine 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); } diff --git a/src/main/java/org/springframework/data/redis/core/convert/CustomConversions.java b/src/main/java/org/springframework/data/redis/core/convert/CustomConversions.java index b3341e8bf..a55f41ce0 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/CustomConversions.java +++ b/src/main/java/org/springframework/data/redis/core/convert/CustomConversions.java @@ -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 converters; - private final Map>> customReadTargetTypes; - private final Map>> customWriteTargetTypes; - private final Map, CacheValue>> rawWriteTargetTypes; + private final Map>> customReadTargetTypes; + private final Map>> customWriteTargetTypes; + private final Map, Optional>> rawWriteTargetTypes; /** * Creates an empty {@link CustomConversions} object. @@ -84,9 +85,9 @@ public class CustomConversions { this.readingPairs = new LinkedHashSet(); this.writingPairs = new LinkedHashSet(); this.customSimpleTypes = new HashSet>(); - this.customReadTargetTypes = new ConcurrentHashMap>>(); - this.customWriteTargetTypes = new ConcurrentHashMap>>(); - this.rawWriteTargetTypes = new ConcurrentHashMap, CacheValue>>(); + this.customReadTargetTypes = new ConcurrentHashMap>>(); + this.customWriteTargetTypes = new ConcurrentHashMap>>(); + this.rawWriteTargetTypes = new ConcurrentHashMap, Optional>>(); List toRegister = new ArrayList(); @@ -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> getCustomTarget(Class sourceType, Class requestedTargetType, Collection 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 Class getOrCreateAndCache(T key, Map>> cache, Producer producer) { - - CacheValue> cacheValue = cache.get(key); - - if (cacheValue != null) { - return cacheValue.getValue(); - } - - Class type = producer.get(); - cache.put(key, CacheValue.> ofNullable(type)); - - return type; - } - - private interface Producer { - - Class get(); + private static Class getOrCreateAndCache(T key, Map>> cache, + Supplier> producer) { + Optional> 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) { diff --git a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java index 499421606..cd66d5679 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java @@ -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> entity = mappingContext.getPersistentEntity(readType); - if (customConversions.hasCustomReadTarget(Map.class, typeToUse.getType())) { + if (customConversions.hasCustomReadTarget(Map.class, readType.getType())) { Map partial = new HashMap(); @@ -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(entity, - new ConverterAwareParameterValueProvider(path, source, conversionService), this.conversionService)); + Object instance = instantiator.createInstance((RedisPersistentEntity) entity.get(), + new PersistentEntityParameterValueProvider(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() { + entity.get().doWithProperties(new PropertyHandler() { @Override - public void doWithPersistentProperty(KeyValuePersistentProperty persistentProperty) { + public void doWithPersistentProperty(RedisPersistentProperty persistentProperty) { String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName(); - PreferredConstructor constructor = entity.getPersistenceConstructor(); + PreferredConstructor 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 targetType = (Class) 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() { + entity.doWithAssociations(new AssociationHandler() { @Override - public void doWithAssociation(Association association) { + public void doWithAssociation(Association 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> 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 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 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 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 persistentPropertyPath = mappingContext + PersistentPropertyPath 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() { + entity.doWithProperties(new PropertyHandler() { @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 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 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 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() { + entity.doWithAssociations(new AssociationHandler() { @Override - public void doWithAssociation(Association association) { + public void doWithAssociation(Association association) { - Object refObject = accessor.getProperty(association.getInverse()); - if (refObject == null) { + Optional 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 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 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 { + private static class ConverterAwareParameterValueProvider implements PropertyValueProvider { private final String path; private final RedisData source; @@ -1005,10 +1041,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean { @Override @SuppressWarnings("unchecked") - public T getPropertyValue(KeyValuePersistentProperty property) { + public Optional 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 diff --git a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java index 3e5846cb5..297b2bbc3 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java @@ -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 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 doResolveIndexesFor(final String keyspace, final String path, TypeInformation typeInformation, PersistentProperty fallback, Object value) { - RedisPersistentEntity entity = mappingContext.getPersistentEntity(typeInformation); + Optional> 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 indexes = new LinkedHashSet(); - entity.doWithProperties(new PropertyHandler() { + entity.get().doWithProperties(new PropertyHandler() { @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 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 diff --git a/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java index bf3c945a1..c9cbf4c35 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java @@ -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, KeyValuePersistentProperty, Object, RedisData> { + extends EntityConverter, RedisPersistentProperty, Object, RedisData> { /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java index d8cd80fe6..53a8d42b7 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java @@ -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> entity = mappingContext.getPersistentEntity(typeInformation); - if (entity == null) { + if (!entity.isPresent()) { return Collections.emptySet(); } - String keyspace = entity.getKeySpace(); + String keyspace = entity.get().getKeySpace(); Set indexes = new HashSet(); diff --git a/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java b/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java index 0e1b4cada..526510725 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java @@ -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 */ -public class BasicRedisPersistentEntity extends BasicKeyValuePersistentEntity +public class BasicRedisPersistentEntity extends BasicKeyValuePersistentEntity implements RedisPersistentEntity { private TimeToLiveAccessor timeToLiveAccessor; @@ -74,17 +75,16 @@ public class BasicRedisPersistentEntity extends BasicKeyValuePersistentEntity * @see org.springframework.data.redis.core.mapping.RedisPersistentEntity#getExplicitTimeToLiveProperty() */ @Override - public RedisPersistentProperty getExplicitTimeToLiveProperty() { - return (RedisPersistentProperty) this.getPersistentProperty(TimeToLive.class); + public Optional 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 extends BasicKeyValuePersistentEntity return null; } - KeyValuePersistentProperty currentIdProperty = getIdProperty(); - boolean currentIdPropertyIsSet = currentIdProperty != null; + Optional 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) { diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java index 886a7ba17..52433c9a2 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java @@ -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, 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 RedisPersistentEntity createPersistentEntity(TypeInformation typeInformation) { return new BasicRedisPersistentEntity(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 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 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> 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(); + } } } diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java index 1997c0df2..fa3966fcb 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java @@ -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 * @since 1.7 */ -public interface RedisPersistentEntity extends KeyValuePersistentEntity { +public interface RedisPersistentEntity extends KeyValuePersistentEntity { /** * Get the {@link TimeToLiveAccessor} associated with the entity. @@ -48,6 +50,6 @@ public interface RedisPersistentEntity extends KeyValuePersistentEntity { * @return can be {@null}. * @since 1.8 */ - PersistentProperty> getExplicitTimeToLiveProperty(); + Optional getExplicitTimeToLiveProperty(); } diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentProperty.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentProperty.java index f856053ca..49bf9684c 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentProperty.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentProperty.java @@ -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 { private static final Set SUPPORTED_ID_PROPERTY_NAMES = new HashSet(); @@ -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 owner, SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + public RedisPersistentProperty(Property property, PersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { + super(property, owner, simpleTypeHolder); } /* diff --git a/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java b/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java index b805ca068..2219a4081 100644 --- a/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java +++ b/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java @@ -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 extends CdiRepositoryBean { public RedisRepositoryBean(Bean keyValueTemplate, Set qualifiers, Class 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 creationalContext, Class repositoryType, Object customImplementation) { + protected T create(CreationalContext creationalContext, Class repositoryType, + Optional 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); } } diff --git a/src/main/java/org/springframework/data/redis/repository/configuration/RedisRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/redis/repository/configuration/RedisRepositoryConfigurationExtension.java index 5c6ffabe6..70ca08e83 100644 --- a/src/main/java/org/springframework/data/redis/repository/configuration/RedisRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/redis/repository/configuration/RedisRepositoryConfigurationExtension.java @@ -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()); diff --git a/src/main/java/org/springframework/data/redis/repository/support/RedisRepositoryFactory.java b/src/main/java/org/springframework/data/redis/repository/support/RedisRepositoryFactory.java index 0fa0dc191..1fad9bf8d 100644 --- a/src/main/java/org/springframework/data/redis/repository/support/RedisRepositoryFactory.java +++ b/src/main/java/org/springframework/data/redis/repository/support/RedisRepositoryFactory.java @@ -80,7 +80,7 @@ public class RedisRepositoryFactory extends KeyValueRepositoryFactory { public EntityInformation getEntityInformation(Class domainClass) { RedisPersistentEntity entity = (RedisPersistentEntity) operations.getMappingContext() - .getPersistentEntity(domainClass); + .getPersistentEntity(domainClass).get(); EntityInformation entityInformation = (EntityInformation) new MappingRedisEntityInformation( entity); diff --git a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java index 69cd30d3e..6060e3559 100644 --- a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java +++ b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.After; import org.junit.AfterClass; @@ -221,7 +222,7 @@ public class RedisKeyValueTemplateTests { template.insert(update); - assertThat(template.findById(rand.id, Person.class), is(equalTo(new Person(rand.id, "rand", "al-thor")))); + assertThat(template.findById(rand.id, Person.class), is(equalTo(Optional.of(new Person(rand.id, "rand", "al-thor"))))); nativeTemplate.execute(new RedisCallback() { @Override @@ -243,7 +244,7 @@ public class RedisKeyValueTemplateTests { template.update(update); - assertThat(template.findById(rand.id, Person.class), is(equalTo(new Person(rand.id, "frodo", "al-thor")))); + assertThat(template.findById(rand.id, Person.class), is(equalTo(Optional.of(new Person(rand.id, "frodo", "al-thor"))))); nativeTemplate.execute(new RedisCallback() { @Override @@ -264,7 +265,7 @@ public class RedisKeyValueTemplateTests { template.doPartialUpdate(update); - assertThat(template.findById(rand.id, Person.class), is(equalTo(new Person(rand.id, null, "baggins")))); + assertThat(template.findById(rand.id, Person.class), is(equalTo(Optional.of(new Person(rand.id, null, "baggins"))))); nativeTemplate.execute(new RedisCallback() { @Override @@ -286,7 +287,7 @@ public class RedisKeyValueTemplateTests { template.doPartialUpdate(update); - assertThat(template.findById(rand.id, Person.class), is(equalTo(new Person(rand.id, null, null)))); + assertThat(template.findById(rand.id, Person.class), is(equalTo(Optional.of(new Person(rand.id, null, null))))); nativeTemplate.execute(new RedisCallback() { @Override @@ -834,9 +835,9 @@ public class RedisKeyValueTemplateTests { Thread.sleep(1100); - WithTtl target = template.findById(source.id, WithTtl.class); - assertThat(target.ttl, is(notNullValue())); - assertThat(target.ttl.doubleValue(), is(closeTo(3D, 1D))); + Optional target = template.findById(source.id, WithTtl.class); + assertThat(target.get().ttl, is(notNullValue())); + assertThat(target.get().ttl.doubleValue(), is(closeTo(3D, 1D))); } @Test // DATAREDIS-523 @@ -851,8 +852,8 @@ public class RedisKeyValueTemplateTests { Thread.sleep(1100); - WithPrimitiveTtl target = template.findById(source.id, WithPrimitiveTtl.class); - assertThat((double) target.ttl, is(closeTo(3D, 1D))); + Optional target = template.findById(source.id, WithPrimitiveTtl.class); + assertThat((double) target.get().ttl, is(closeTo(3D, 1D))); } @Test // DATAREDIS-523 @@ -891,8 +892,8 @@ public class RedisKeyValueTemplateTests { } }); - WithTtl target = template.findById(source.id, WithTtl.class); - assertThat(target.ttl, is(-1L)); + Optional target = template.findById(source.id, WithTtl.class); + assertThat(target.get().ttl, is(-1L)); } @EqualsAndHashCode diff --git a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java index e1e483a12..6acca575b 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java @@ -1237,6 +1237,7 @@ public class MappingRedisConverterUnitTests { di.object = "foo"; RedisData rd = write(di); + System.out.println(rd.getBucket().toString()); TypeWithObjectValueTypes result = converter.read(TypeWithObjectValueTypes.class, rd); assertThat(result.object, instanceOf(String.class)); diff --git a/src/test/java/org/springframework/data/redis/core/convert/PathIndexResolverUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/PathIndexResolverUnitTests.java index c07765d7b..d9cfcfea8 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/PathIndexResolverUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/PathIndexResolverUnitTests.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.hamcrest.core.IsCollectionContaining; @@ -253,7 +254,7 @@ public class PathIndexResolverUnitTests { public void resolveIndexShouldReturnDataWhenNoIndexConfiguredButPropertyAnnotated() { when(propertyMock.isAnnotationPresent(eq(Indexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(createIndexedInstance()); + when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(Optional.of(createIndexedInstance())); assertThat(resolve("foo", "rand"), notNullValue()); } @@ -263,7 +264,7 @@ public class PathIndexResolverUnitTests { when(propertyMock.isCollectionLike()).thenReturn(true); when(propertyMock.isAnnotationPresent(eq(Indexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(createIndexedInstance()); + when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(Optional.of(createIndexedInstance())); IndexedData index = resolve("list.[0].name", "rand"); @@ -275,7 +276,7 @@ public class PathIndexResolverUnitTests { when(propertyMock.isMap()).thenReturn(true); when(propertyMock.isAnnotationPresent(eq(Indexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(createIndexedInstance()); + when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(Optional.of(createIndexedInstance())); IndexedData index = resolve("map.[foo].name", "rand"); @@ -287,7 +288,7 @@ public class PathIndexResolverUnitTests { when(propertyMock.isMap()).thenReturn(true); when(propertyMock.isAnnotationPresent(eq(Indexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(createIndexedInstance()); + when(propertyMock.findAnnotation(eq(Indexed.class))).thenReturn(Optional.of(createIndexedInstance())); IndexedData index = resolve("map.[0].name", "rand"); @@ -449,7 +450,7 @@ public class PathIndexResolverUnitTests { when(propertyMock.isMap()).thenReturn(true); when(propertyMock.isAnnotationPresent(eq(GeoIndexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(GeoIndexed.class))).thenReturn(createGeoIndexedInstance()); + when(propertyMock.findAnnotation(eq(GeoIndexed.class))).thenReturn(Optional.of(createGeoIndexedInstance())); IndexedData index = resolve("location", new Point(1D, 2D)); @@ -461,7 +462,7 @@ public class PathIndexResolverUnitTests { when(propertyMock.isMap()).thenReturn(true); when(propertyMock.isAnnotationPresent(eq(GeoIndexed.class))).thenReturn(true); - when(propertyMock.findAnnotation(eq(GeoIndexed.class))).thenReturn(createGeoIndexedInstance()); + when(propertyMock.findAnnotation(eq(GeoIndexed.class))).thenReturn(Optional.of(createGeoIndexedInstance())); IndexedData index = resolve("property.location", new Point(1D, 2D)); diff --git a/src/test/java/org/springframework/data/redis/core/convert/SpelIndexResolverUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/SpelIndexResolverUnitTests.java index 3d3230565..ee298132e 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/SpelIndexResolverUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/SpelIndexResolverUnitTests.java @@ -24,11 +24,11 @@ import java.util.Set; import org.junit.Before; import org.junit.Test; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; import org.springframework.data.redis.core.convert.KeyspaceConfiguration.KeyspaceSettings; import org.springframework.data.redis.core.index.IndexConfiguration; 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.ClassTypeInformation; import org.springframework.expression.AccessException; import org.springframework.expression.BeanResolver; @@ -57,7 +57,7 @@ public class SpelIndexResolverUnitTests { RedisMappingContext mappingContext; - KeyValuePersistentEntity entity; + RedisPersistentEntity entity; @Before public void setup() { diff --git a/src/test/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntityUnitTests.java b/src/test/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntityUnitTests.java index 5c060234d..638446819 100644 --- a/src/test/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntityUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntityUnitTests.java @@ -22,6 +22,7 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.io.Serializable; +import java.util.Optional; import org.junit.Before; import org.junit.Rule; @@ -31,7 +32,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; 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.TimeToLiveAccessor; import org.springframework.data.redis.core.convert.ConversionTestEntities; @@ -68,10 +68,10 @@ public class BasicRedisPersistentEntityUnitTests { expectedException.expectMessage("Attempt to add id property"); expectedException.expectMessage("but already have an property"); - KeyValuePersistentProperty property1 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property1 = mock(RedisPersistentProperty.class); when(property1.isIdProperty()).thenReturn(true); - KeyValuePersistentProperty property2 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property2 = mock(RedisPersistentProperty.class); when(property2.isIdProperty()).thenReturn(true); entity.addPersistentProperty(property1); @@ -86,11 +86,11 @@ public class BasicRedisPersistentEntityUnitTests { expectedException.expectMessage("Attempt to add explicit id property"); expectedException.expectMessage("but already have an property"); - KeyValuePersistentProperty property1 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property1 = mock(RedisPersistentProperty.class); when(property1.isIdProperty()).thenReturn(true); when(property1.isAnnotationPresent(any(Class.class))).thenReturn(true); - KeyValuePersistentProperty property2 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property2 = mock(RedisPersistentProperty.class); when(property2.isIdProperty()).thenReturn(true); when(property2.isAnnotationPresent(any(Class.class))).thenReturn(true); @@ -102,16 +102,16 @@ public class BasicRedisPersistentEntityUnitTests { @SuppressWarnings("unchecked") public void explicitIdPropertiyShouldBeFavoredOverNonExplicit() { - KeyValuePersistentProperty property1 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property1 = mock(RedisPersistentProperty.class); when(property1.isIdProperty()).thenReturn(true); - KeyValuePersistentProperty property2 = mock(RedisPersistentProperty.class); + RedisPersistentProperty property2 = mock(RedisPersistentProperty.class); when(property2.isIdProperty()).thenReturn(true); when(property2.isAnnotationPresent(any(Class.class))).thenReturn(true); entity.addPersistentProperty(property1); entity.addPersistentProperty(property2); - assertThat(entity.getIdProperty(), is(equalTo(property2))); + assertThat(entity.getIdProperty(), is(equalTo(Optional.of(property2)))); } } diff --git a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java index 0a72ab7dc..caca5edf3 100644 --- a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java +++ b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.hamcrest.core.IsNull; import org.junit.Before; @@ -80,8 +81,8 @@ public abstract class RedisRepositoryIntegrationTestBase { assertThat(repo.count(), is(2L)); - assertThat(repo.findOne(rand.id), is(rand)); - assertThat(repo.findOne(egwene.id), is(egwene)); + assertThat(repo.findOne(rand.id), is(Optional.of(rand))); + assertThat(repo.findOne(egwene.id), is(Optional.of(egwene))); assertThat(repo.findByFirstname("rand").size(), is(1)); assertThat(repo.findByFirstname("rand"), hasItem(rand)); @@ -130,15 +131,15 @@ public abstract class RedisRepositoryIntegrationTestBase { repo.save(moiraine); // find and assert current location set correctly - Person loaded = repo.findOne(moiraine.getId()); - assertThat(loaded.city, is(tarValon)); + Optional loaded = repo.findOne(moiraine.getId()); + assertThat(loaded.get().city, is(tarValon)); // remove reference location data kvTemplate.delete("1", City.class); // find and assert the location is gone - Person reLoaded = repo.findOne(moiraine.getId()); - assertThat(reLoaded.city, IsNull.nullValue()); + Optional reLoaded = repo.findOne(moiraine.getId()); + assertThat(reLoaded.get().city, IsNull.nullValue()); } @Test // DATAREDIS-425