DATAKV-159 - Integrate DATACMNS Java 8 upgrade.

Related to: DATACMNS-867
This commit is contained in:
Christoph Strobl
2017-01-23 11:38:56 +01:00
parent c148347e93
commit d3fe2f2e56
19 changed files with 114 additions and 93 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.data.keyvalue.core; package org.springframework.data.keyvalue.core;
import java.io.Serializable; import java.io.Serializable;
import java.util.Optional;
import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.IdentifierAccessor;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
@@ -60,7 +61,7 @@ class GeneratingIdAccessor implements IdentifierAccessor {
* @see org.springframework.data.keyvalue.core.IdentifierAccessor#getIdentifier() * @see org.springframework.data.keyvalue.core.IdentifierAccessor#getIdentifier()
*/ */
@Override @Override
public Object getIdentifier() { public Optional<Object> getIdentifier() {
return accessor.getProperty(identifierProperty); return accessor.getProperty(identifierProperty);
} }
@@ -72,14 +73,14 @@ class GeneratingIdAccessor implements IdentifierAccessor {
*/ */
public Object getOrGenerateIdentifier() { public Object getOrGenerateIdentifier() {
Serializable existingIdentifier = (Serializable) getIdentifier(); Optional<Object> existingIdentifier = getIdentifier();
if (existingIdentifier != null) { if (existingIdentifier.isPresent()) {
return existingIdentifier; return existingIdentifier.get();
} }
Object generatedIdentifier = generator.generateIdentifierOfType(identifierProperty.getTypeInformation()); Object generatedIdentifier = generator.generateIdentifierOfType(identifierProperty.getTypeInformation());
accessor.setProperty(identifierProperty, generatedIdentifier); accessor.setProperty(identifierProperty, Optional.ofNullable(generatedIdentifier));
return generatedIdentifier; return generatedIdentifier;
} }

View File

@@ -16,6 +16,7 @@
package org.springframework.data.keyvalue.core; package org.springframework.data.keyvalue.core;
import java.io.Serializable; import java.io.Serializable;
import java.util.Optional;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@@ -73,7 +74,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type must not be {@literal null}. * @param type must not be {@literal null}.
* @return null if not found. * @return null if not found.
*/ */
<T> T findById(Serializable id, Class<T> type); <T> Optional<T> findById(Serializable id, Class<T> type);
/** /**
* Execute operation against underlying store. * Execute operation against underlying store.
@@ -102,7 +103,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type must not be {@literal null}. * @param type must not be {@literal null}.
* @return * @return
*/ */
<T> Iterable<T> findInRange(int offset, int rows, Class<T> type); <T> Iterable<T> findInRange(long offset, int rows, Class<T> type);
/** /**
* Get all elements in given range ordered by sort. Respects {@link KeySpace} if present and therefore returns all * Get all elements in given range ordered by sort. Respects {@link KeySpace} if present and therefore returns all
@@ -114,7 +115,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type * @param type
* @return * @return
*/ */
<T> Iterable<T> findInRange(int offset, int rows, Sort sort, Class<T> type); <T> Iterable<T> findInRange(long offset, int rows, Sort sort, Class<T> type);
/** /**
* @param objectToUpdate must not be {@literal null}. * @param objectToUpdate must not be {@literal null}.

View File

@@ -19,6 +19,7 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
@@ -33,12 +34,11 @@ import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.core.query.KeyValueQuery; import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/** /**
* Basic implementation of {@link KeyValueOperations}. * Basic implementation of {@link KeyValueOperations}.
@@ -131,16 +131,25 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
@Override @Override
public <T> T insert(T objectToInsert) { public <T> T insert(T objectToInsert) {
PersistentEntity<?, ?> entity = this.mappingContext.getPersistentEntity(ClassUtils.getUserClass(objectToInsert)); KeyValuePersistentEntity<?> entity = getKeyValuePersistentEntity(objectToInsert);
GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert), GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert),
entity.getIdProperty(), identifierGenerator); entity.getIdProperty()
.orElseThrow(() -> new IllegalArgumentException("Unable to extract 'id' for object to be deleted")),
identifierGenerator);
Object id = generatingIdAccessor.getOrGenerateIdentifier(); Object id = generatingIdAccessor.getOrGenerateIdentifier();
insert((Serializable) id, objectToInsert); insert((Serializable) id, objectToInsert);
return objectToInsert; return objectToInsert;
} }
private KeyValuePersistentEntity<?> getKeyValuePersistentEntity(Object objectToInsert) {
return this.mappingContext.getPersistentEntity(ClassUtils.getUserClass(objectToInsert))
.orElseThrow(() -> new IllegalArgumentException(
String.format("Unable to find PersistentEntity for %s", ObjectUtils.nullSafeClassName(objectToInsert))));
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.keyvalue.core.KeyValueOperations#insert(java.io.Serializable, java.lang.Object) * @see org.springframework.data.keyvalue.core.KeyValueOperations#insert(java.io.Serializable, java.lang.Object)
@@ -161,8 +170,8 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
public Void doInKeyValue(KeyValueAdapter adapter) { public Void doInKeyValue(KeyValueAdapter adapter) {
if (adapter.contains(id, keyspace)) { if (adapter.contains(id, keyspace)) {
throw new DuplicateKeyException(String.format( throw new DuplicateKeyException(
"Cannot insert existing object with id %s!. Please use update.", id)); String.format("Cannot insert existing object with id %s!. Please use update.", id));
} }
adapter.put(id, objectToInsert, keyspace); adapter.put(id, objectToInsert, keyspace);
@@ -181,15 +190,14 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
@Override @Override
public void update(Object objectToUpdate) { public void update(Object objectToUpdate) {
PersistentEntity<?, ? extends PersistentProperty> entity = this.mappingContext.getPersistentEntity(ClassUtils KeyValuePersistentEntity<?> entity = getKeyValuePersistentEntity(objectToUpdate);
.getUserClass(objectToUpdate));
if (!entity.hasIdProperty()) { if (!entity.hasIdProperty()) {
throw new InvalidDataAccessApiUsageException(String.format("Cannot determine id for type %s", throw new InvalidDataAccessApiUsageException(
ClassUtils.getUserClass(objectToUpdate))); String.format("Cannot determine id for type %s", ClassUtils.getUserClass(objectToUpdate)));
} }
update((Serializable) entity.getIdentifierAccessor(objectToUpdate).getIdentifier(), objectToUpdate); update((Serializable) entity.getIdentifierAccessor(objectToUpdate).getIdentifier().get(), objectToUpdate);
} }
/* /*
@@ -214,8 +222,8 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
} }
}); });
potentiallyPublishEvent(KeyValueEvent potentiallyPublishEvent(
.afterUpdate(id, keyspace, objectToUpdate.getClass(), objectToUpdate, existing)); KeyValueEvent.afterUpdate(id, keyspace, objectToUpdate.getClass(), objectToUpdate, existing));
} }
/* /*
@@ -256,7 +264,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
* @see org.springframework.data.keyvalue.core.KeyValueOperations#findById(java.io.Serializable, java.lang.Class) * @see org.springframework.data.keyvalue.core.KeyValueOperations#findById(java.io.Serializable, java.lang.Class)
*/ */
@Override @Override
public <T> T findById(final Serializable id, final Class<T> type) { public <T> Optional<T> findById(final Serializable id, final Class<T> type) {
Assert.notNull(id, "Id for object to be inserted must not be null!"); Assert.notNull(id, "Id for object to be inserted must not be null!");
Assert.notNull(type, "Type to fetch must not be null!"); Assert.notNull(type, "Type to fetch must not be null!");
@@ -283,7 +291,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
potentiallyPublishEvent(KeyValueEvent.afterGet(id, keyspace, type, result)); potentiallyPublishEvent(KeyValueEvent.afterGet(id, keyspace, type, result));
return result; return Optional.ofNullable(result);
} }
/* /*
@@ -321,9 +329,10 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
public <T> T delete(T objectToDelete) { public <T> T delete(T objectToDelete) {
Class<T> type = (Class<T>) ClassUtils.getUserClass(objectToDelete); Class<T> type = (Class<T>) ClassUtils.getUserClass(objectToDelete);
PersistentEntity<?, ? extends PersistentProperty> entity = this.mappingContext.getPersistentEntity(type); KeyValuePersistentEntity<?> entity = getKeyValuePersistentEntity(objectToDelete);
return delete((Serializable) entity.getIdentifierAccessor(objectToDelete).getIdentifier(), type); return delete((Serializable) entity.getIdentifierAccessor(objectToDelete).getIdentifier()
.orElseThrow(() -> new IllegalArgumentException("Unable to extract 'id' for object to be deleted")), type);
} }
/* /*
@@ -423,21 +432,21 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(int, int, java.lang.Class) * @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(long, int, java.lang.Class)
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public <T> Iterable<T> findInRange(int offset, int rows, Class<T> type) { public <T> Iterable<T> findInRange(long offset, int rows, Class<T> type) {
return find(new KeyValueQuery().skip(offset).limit(rows), type); return find(new KeyValueQuery().skip(offset).limit(rows), type);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(int, int, org.springframework.data.domain.Sort, java.lang.Class) * @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(long, int, org.springframework.data.domain.Sort, java.lang.Class)
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public <T> Iterable<T> findInRange(int offset, int rows, Sort sort, Class<T> type) { public <T> Iterable<T> findInRange(long offset, int rows, Sort sort, Class<T> type) {
return find(new KeyValueQuery(sort).skip(offset).limit(rows), type); return find(new KeyValueQuery(sort).skip(offset).limit(rows), type);
} }
@@ -476,7 +485,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
} }
private String resolveKeySpace(Class<?> type) { private String resolveKeySpace(Class<?> type) {
return this.mappingContext.getPersistentEntity(type).getKeySpace(); return this.mappingContext.getPersistentEntity(type).get().getKeySpace();
} }
private RuntimeException resolveExceptionIfPossible(RuntimeException e) { private RuntimeException resolveExceptionIfPossible(RuntimeException e) {

View File

@@ -92,7 +92,7 @@ public abstract class QueryEngine<ADAPTER extends KeyValueAdapter, CRITERIA, SOR
* @param keyspace * @param keyspace
* @return * @return
*/ */
public abstract Collection<?> execute(CRITERIA criteria, SORT sort, int offset, int rows, Serializable keyspace); public abstract Collection<?> execute(CRITERIA criteria, SORT sort, long offset, int rows, Serializable keyspace);
/** /**
* @param criteria * @param criteria
@@ -104,7 +104,7 @@ public abstract class QueryEngine<ADAPTER extends KeyValueAdapter, CRITERIA, SOR
* @return * @return
* @since 1.1 * @since 1.1
*/ */
public <T> Collection<T> execute(CRITERIA criteria, SORT sort, int offset, int rows, Serializable keyspace, public <T> Collection<T> execute(CRITERIA criteria, SORT sort, long offset, int rows, Serializable keyspace,
Class<T> type) { Class<T> type) {
return (Collection<T>) execute(criteria, sort, offset, rows, keyspace); return (Collection<T>) execute(criteria, sort, offset, rows, keyspace);
} }

View File

@@ -51,7 +51,7 @@ class SpelQueryEngine<T extends KeyValueAdapter> extends QueryEngine<KeyValueAda
* @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable) * @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable)
*/ */
@Override @Override
public Collection<?> execute(SpelCriteria criteria, Comparator<?> sort, int offset, int rows, Serializable keyspace) { public Collection<?> execute(SpelCriteria criteria, Comparator<?> sort, long offset, int rows, Serializable keyspace) {
return sortAndFilterMatchingRange(getAdapter().getAllOf(keyspace), criteria, sort, offset, rows); return sortAndFilterMatchingRange(getAdapter().getAllOf(keyspace), criteria, sort, offset, rows);
} }
@@ -65,7 +65,7 @@ class SpelQueryEngine<T extends KeyValueAdapter> extends QueryEngine<KeyValueAda
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private List<?> sortAndFilterMatchingRange(Iterable<?> source, SpelCriteria criteria, Comparator sort, int offset, private List<?> sortAndFilterMatchingRange(Iterable<?> source, SpelCriteria criteria, Comparator sort, long offset,
int rows) { int rows) {
List<?> tmp = IterableConverter.toList(source); List<?> tmp = IterableConverter.toList(source);
@@ -76,7 +76,7 @@ class SpelQueryEngine<T extends KeyValueAdapter> extends QueryEngine<KeyValueAda
return filterMatchingRange(tmp, criteria, offset, rows); return filterMatchingRange(tmp, criteria, offset, rows);
} }
private static <S> List<S> filterMatchingRange(Iterable<S> source, SpelCriteria criteria, int offset, int rows) { private static <S> List<S> filterMatchingRange(Iterable<S> source, SpelCriteria criteria, long offset, int rows) {
List<S> result = new ArrayList<S>(); List<S> result = new ArrayList<S>();

View File

@@ -17,6 +17,7 @@ package org.springframework.data.keyvalue.core;
import java.util.Comparator; import java.util.Comparator;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.NullHandling; import org.springframework.data.domain.Sort.NullHandling;
import org.springframework.data.domain.Sort.Order; import org.springframework.data.domain.Sort.Order;
@@ -52,7 +53,7 @@ class SpelSortAccessor implements SortAccessor<Comparator<?>> {
@Override @Override
public Comparator<?> resolve(KeyValueQuery<?> query) { public Comparator<?> resolve(KeyValueQuery<?> query) {
if (query == null || query.getSort() == null) { if (query == null || query.getSort() == null || Sort.unsorted().equals(query.getSort())) {
return null; return null;
} }

View File

@@ -22,6 +22,7 @@ import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mapping.model.SimpleTypeHolder;
/** /**
@@ -31,9 +32,9 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
*/ */
public class KeyValuePersistentProperty extends AnnotationBasedPersistentProperty<KeyValuePersistentProperty> { public class KeyValuePersistentProperty extends AnnotationBasedPersistentProperty<KeyValuePersistentProperty> {
public KeyValuePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, public KeyValuePersistentProperty(Property property, PersistentEntity<?, KeyValuePersistentProperty> owner,
PersistentEntity<?, KeyValuePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) { SimpleTypeHolder simpleTypeHolder) {
super(field, propertyDescriptor, owner, simpleTypeHolder); super(property, owner, simpleTypeHolder);
} }
/* /*

View File

@@ -24,6 +24,7 @@ import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.mapping.context.AbstractMappingContext; import org.springframework.data.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.context.MappingContext; 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.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
@@ -57,13 +58,8 @@ public class KeyValueMappingContext extends
return new BasicKeyValuePersistentEntity<T>(typeInformation, fallbackKeySpaceResolver); return new BasicKeyValuePersistentEntity<T>(typeInformation, fallbackKeySpaceResolver);
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
*/
@Override @Override
protected KeyValuePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, protected KeyValuePersistentProperty createPersistentProperty(Property property, KeyValuePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
KeyValuePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) { return new KeyValuePersistentProperty(property, owner, simpleTypeHolder);
return new KeyValuePersistentProperty(field, descriptor, owner, simpleTypeHolder);
} }
} }

View File

@@ -24,7 +24,7 @@ import org.springframework.data.domain.Sort;
public class KeyValueQuery<T> { public class KeyValueQuery<T> {
private Sort sort; private Sort sort;
private int offset = -1; private long offset = -1;
private int rows = -1; private int rows = -1;
private T criteria; private T criteria;
@@ -74,7 +74,7 @@ public class KeyValueQuery<T> {
* *
* @return negative value if not set. * @return negative value if not set.
*/ */
public int getOffset() { public long getOffset() {
return this.offset; return this.offset;
} }
@@ -92,7 +92,7 @@ public class KeyValueQuery<T> {
* *
* @param offset use negative value for none. * @param offset use negative value for none.
*/ */
public void setOffset(int offset) { public void setOffset(long offset) {
this.offset = offset; this.offset = offset;
} }
@@ -139,7 +139,7 @@ public class KeyValueQuery<T> {
* @param offset * @param offset
* @return * @return
*/ */
public KeyValueQuery<T> skip(int offset) { public KeyValueQuery<T> skip(long offset) {
setOffset(offset); setOffset(offset);
return this; return this;
} }

View File

@@ -18,6 +18,7 @@ package org.springframework.data.keyvalue.repository.config;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -153,16 +154,16 @@ public abstract class KeyValueRepositoryConfigurationExtension extends Repositor
registerIfNotAlreadyRegistered(mappingContextDefinition, registry, MAPPING_CONTEXT_BEAN_NAME, configurationSource); registerIfNotAlreadyRegistered(mappingContextDefinition, registry, MAPPING_CONTEXT_BEAN_NAME, configurationSource);
String keyValueTemplateName = configurationSource.getAttribute(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE); Optional<String> keyValueTemplateName = configurationSource.getAttribute(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE);
// No custom template reference configured and no matching bean definition found // No custom template reference configured and no matching bean definition found
if (getDefaultKeyValueTemplateRef().equals(keyValueTemplateName) if (keyValueTemplateName.isPresent() && getDefaultKeyValueTemplateRef().equals(keyValueTemplateName.get())
&& !registry.containsBeanDefinition(keyValueTemplateName)) { && !registry.containsBeanDefinition(keyValueTemplateName.get())) {
AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource); AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource);
if (beanDefinition != null) { if (beanDefinition != null) {
registerIfNotAlreadyRegistered(beanDefinition, registry, keyValueTemplateName, configurationSource.getSource()); registerIfNotAlreadyRegistered(beanDefinition, registry, keyValueTemplateName.get(), configurationSource.getSource());
} }
} }
} }

View File

@@ -16,8 +16,10 @@
package org.springframework.data.keyvalue.repository.query; package org.springframework.data.keyvalue.repository.query;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Optional;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@@ -85,7 +87,7 @@ public class KeyValuePartTreeQuery implements RepositoryQuery {
ParameterAccessor accessor = new ParametersParameterAccessor(getQueryMethod().getParameters(), parameters); ParameterAccessor accessor = new ParametersParameterAccessor(getQueryMethod().getParameters(), parameters);
KeyValueQuery<?> query = prepareQuery(parameters); KeyValueQuery<?> query = prepareQuery(parameters);
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(accessor); ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(Optional.ofNullable(accessor));
return processor.processResult(doExecute(parameters, query)); return processor.processResult(doExecute(parameters, query));
} }
@@ -149,15 +151,15 @@ public class KeyValuePartTreeQuery implements RepositoryQuery {
Pageable pageable = accessor.getPageable(); Pageable pageable = accessor.getPageable();
Sort sort = accessor.getSort(); Sort sort = accessor.getSort();
query.setOffset(pageable == null ? -1 : pageable.getOffset()); query.setOffset(pageable != null && Pageable.NONE.equals(pageable) ? -1L : pageable.getOffset());
if (pageable != null) { if (pageable != null && !Pageable.NONE.equals(pageable)) {
query.setRows(pageable.getPageSize()); query.setRows(pageable.getPageSize());
} else if (instance.getRows() >= 0) { } else if (instance.getRows() >= 0) {
query.setRows(instance.getRows()); query.setRows(instance.getRows());
} }
query.setSort(sort == null ? instance.getSort() : sort); query.setSort(sort == null || Sort.unsorted().equals(sort) ? instance.getSort() : sort);
return query; return query;
} }

View File

@@ -15,11 +15,12 @@
*/ */
package org.springframework.data.keyvalue.repository.support; package org.springframework.data.keyvalue.repository.support;
import static org.springframework.data.querydsl.QueryDslUtils.*; import static org.springframework.data.querydsl.QuerydslUtils.*;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Optional;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.data.keyvalue.core.KeyValueOperations; import org.springframework.data.keyvalue.core.KeyValueOperations;
@@ -28,7 +29,7 @@ import org.springframework.data.keyvalue.repository.query.SpelQueryCreator;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryInformation;
@@ -112,7 +113,7 @@ public class KeyValueRepositoryFactory extends RepositoryFactorySupport {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) { public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
PersistentEntity<T, ?> entity = (PersistentEntity<T, ?>) context.getPersistentEntity(domainClass); PersistentEntity<T, ?> entity = (PersistentEntity<T, ?>) context.getPersistentEntity(domainClass).get();
PersistentEntityInformation<T, ID> entityInformation = new PersistentEntityInformation<T, ID>(entity); PersistentEntityInformation<T, ID> entityInformation = new PersistentEntityInformation<T, ID>(entity);
return entityInformation; return entityInformation;
@@ -146,7 +147,7 @@ public class KeyValueRepositoryFactory extends RepositoryFactorySupport {
* @return * @return
*/ */
private static boolean isQueryDslRepository(Class<?> repositoryInterface) { private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface); return QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
} }
/* /*
@@ -154,9 +155,9 @@ public class KeyValueRepositoryFactory extends RepositoryFactorySupport {
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
*/ */
@Override @Override
protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) { protected Optional<QueryLookupStrategy> getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) {
return new KeyValueQueryLookupStrategy(key, evaluationContextProvider, this.keyValueOperations, this.queryCreator, return Optional.of(new KeyValueQueryLookupStrategy(key, evaluationContextProvider, this.keyValueOperations, this.queryCreator,
this.repositoryQueryType); this.repositoryQueryType));
} }
/** /**

View File

@@ -26,7 +26,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.core.KeyValueOperations; import org.springframework.data.keyvalue.core.KeyValueOperations;
import org.springframework.data.keyvalue.repository.KeyValueRepository; import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.data.querydsl.EntityPathResolver; import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.EntityInformation;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@@ -49,7 +49,7 @@ import com.querydsl.core.types.dsl.PathBuilder;
* @param <ID> the identifier type of the domain type * @param <ID> the identifier type of the domain type
*/ */
public class QuerydslKeyValueRepository<T, ID extends Serializable> extends SimpleKeyValueRepository<T, ID> public class QuerydslKeyValueRepository<T, ID extends Serializable> extends SimpleKeyValueRepository<T, ID>
implements QueryDslPredicateExecutor<T> { implements QuerydslPredicateExecutor<T> {
private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE; private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;

View File

@@ -18,6 +18,7 @@ package org.springframework.data.keyvalue.repository.support;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
@@ -74,7 +75,7 @@ public class SimpleKeyValueRepository<T, ID extends Serializable> implements Key
if (pageable == null) { if (pageable == null) {
List<T> result = findAll(); List<T> result = findAll();
return new PageImpl<T>(result, null, result.size()); return new PageImpl<T>(result, Pageable.NONE, result.size());
} }
Iterable<T> content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(), Iterable<T> content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(),
@@ -96,7 +97,7 @@ public class SimpleKeyValueRepository<T, ID extends Serializable> implements Key
if (entityInformation.isNew(entity)) { if (entityInformation.isNew(entity)) {
operations.insert(entity); operations.insert(entity);
} else { } else {
operations.update(entityInformation.getId(entity), entity); operations.update(entityInformation.getId(entity).get(), entity);
} }
return entity; return entity;
} }
@@ -120,7 +121,7 @@ public class SimpleKeyValueRepository<T, ID extends Serializable> implements Key
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable) * @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
*/ */
@Override @Override
public T findOne(ID id) { public Optional<T> findOne(ID id) {
return operations.findById(id, entityInformation.getJavaType()); return operations.findById(id, entityInformation.getJavaType());
} }
@@ -153,10 +154,10 @@ public class SimpleKeyValueRepository<T, ID extends Serializable> implements Key
for (ID id : ids) { for (ID id : ids) {
T candidate = findOne(id); Optional<T> candidate = findOne(id);
if (candidate != null) { if (candidate.isPresent()) {
result.add(candidate); result.add(candidate.get());
} }
} }
@@ -187,7 +188,7 @@ public class SimpleKeyValueRepository<T, ID extends Serializable> implements Key
*/ */
@Override @Override
public void delete(T entity) { public void delete(T entity) {
delete(entityInformation.getId(entity)); delete(entityInformation.getId(entity).orElseThrow(() -> new IllegalArgumentException("Cannot delete entity with 'null' id.")));
} }
/* /*

View File

@@ -29,6 +29,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.List; import java.util.List;
import java.util.Optional;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -113,28 +114,28 @@ public class KeyValueTemplateTests {
operations.insert(source); operations.insert(source);
assertThat(operations.findById("one", ClassWithStringId.class), is(source)); assertThat(operations.findById("one", ClassWithStringId.class), is(Optional.of(source)));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
public void findByIdShouldReturnObjectWithMatchingIdAndType() { public void findByIdShouldReturnObjectWithMatchingIdAndType() {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
assertThat(operations.findById("1", Foo.class), is(FOO_ONE)); assertThat(operations.findById("1", Foo.class), is(Optional.of(FOO_ONE)));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
public void findByIdSouldReturnNullIfNoMatchingIdFound() { public void findByIdSouldReturnOptionalEmptyIfNoMatchingIdFound() {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
assertThat(operations.findById("2", Foo.class), nullValue()); assertThat(operations.findById("2", Foo.class), is(Optional.empty()));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
public void findByIdShouldReturnNullIfNoMatchingTypeFound() { public void findByIdShouldReturnOptionalEmptyIfNoMatchingTypeFound() {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
assertThat(operations.findById("1", Bar.class), nullValue()); assertThat(operations.findById("1", Bar.class), is(Optional.empty()));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
@@ -163,7 +164,7 @@ public class KeyValueTemplateTests {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
operations.update("1", FOO_TWO); operations.update("1", FOO_TWO);
assertThat(operations.findById("1", Foo.class), is(FOO_TWO)); assertThat(operations.findById("1", Foo.class), is(Optional.of(FOO_TWO)));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
@@ -172,7 +173,7 @@ public class KeyValueTemplateTests {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
operations.update("1", BAR_ONE); operations.update("1", BAR_ONE);
assertThat(operations.findById("1", Foo.class), is(FOO_ONE)); assertThat(operations.findById("1", Foo.class), is(Optional.of(FOO_ONE)));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
@@ -180,7 +181,7 @@ public class KeyValueTemplateTests {
operations.insert("1", FOO_ONE); operations.insert("1", FOO_ONE);
operations.delete("1", Foo.class); operations.delete("1", Foo.class);
assertThat(operations.findById("1", Foo.class), nullValue()); assertThat(operations.findById("1", Foo.class), is(Optional.empty()));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525

View File

@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@@ -167,8 +168,8 @@ public class KeyValueTemplateUnitTests {
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
public void findByIdShouldReturnNullWhenNoElementsPresent() { public void findByIdShouldReturnOptionalEmptyWhenNoElementsPresent() {
assertNull(template.findById("1", Foo.class)); assertThat(template.findById("1", Foo.class), is(Optional.empty()));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
@@ -214,7 +215,7 @@ public class KeyValueTemplateUnitTests {
template.findInRange(1, 5, Foo.class); template.findInRange(1, 5, Foo.class);
verify(adapterMock, times(1)).find(captor.capture(), eq(Foo.class.getName()), eq(Foo.class)); verify(adapterMock, times(1)).find(captor.capture(), eq(Foo.class.getName()), eq(Foo.class));
assertThat(captor.getValue().getOffset(), is(1)); assertThat(captor.getValue().getOffset(), is(1L));
assertThat(captor.getValue().getRows(), is(5)); assertThat(captor.getValue().getRows(), is(5));
assertThat(captor.getValue().getCritieria(), nullValue()); assertThat(captor.getValue().getCritieria(), nullValue());
} }
@@ -325,7 +326,7 @@ public class KeyValueTemplateUnitTests {
public void insertSouldRespectTypeAliasAndFilterNonMatching() { public void insertSouldRespectTypeAliasAndFilterNonMatching() {
template.insert("1", ALIASED); template.insert("1", ALIASED);
assertThat(template.findById("1", SUBCLASS_OF_ALIASED.getClass()), nullValue()); assertThat(template.findById("1", SUBCLASS_OF_ALIASED.getClass()), is(Optional.empty()));
} }
@Test(expected = IllegalArgumentException.class) // DATACMNS-525 @Test(expected = IllegalArgumentException.class) // DATACMNS-525

View File

@@ -18,7 +18,9 @@ package org.springframework.data.keyvalue.repository;
import static org.mockito.Matchers.*; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -91,7 +93,9 @@ public class SimpleKeyValueRepositoryUnitTests {
@Test // DATACMNS-525 @Test // DATACMNS-525
public void deleteEntity() { public void deleteEntity() {
Foo one = repo.save(new Foo("one")); Foo one = new Foo("one");
one.id = "1";
repo.save(one);
repo.delete(one); repo.delete(one);
verify(opsMock, times(1)).delete(eq(one.getId()), eq(Foo.class)); verify(opsMock, times(1)).delete(eq(one.getId()), eq(Foo.class));
@@ -116,6 +120,7 @@ public class SimpleKeyValueRepositoryUnitTests {
@Test // DATACMNS-525 @Test // DATACMNS-525
public void findAllIds() { public void findAllIds() {
when(opsMock.findById(any(Serializable.class), any(Class.class))).thenReturn(Optional.empty());
repo.findAll(Arrays.asList("one", "two", "three")); repo.findAll(Arrays.asList("one", "two", "three"));
verify(opsMock, times(3)).findById(anyString(), eq(Foo.class)); verify(opsMock, times(3)).findById(anyString(), eq(Foo.class));
@@ -126,7 +131,7 @@ public class SimpleKeyValueRepositoryUnitTests {
repo.findAll(new PageRequest(10, 15)); repo.findAll(new PageRequest(10, 15));
verify(opsMock, times(1)).findInRange(eq(150), eq(15), isNull(Sort.class), eq(Foo.class)); verify(opsMock, times(1)).findInRange(eq(150L), eq(15), eq(Sort.unsorted()), eq(Foo.class));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525
@@ -135,7 +140,7 @@ public class SimpleKeyValueRepositoryUnitTests {
Sort sort = new Sort("for", "bar"); Sort sort = new Sort("for", "bar");
repo.findAll(new PageRequest(10, 15, sort)); repo.findAll(new PageRequest(10, 15, sort));
verify(opsMock, times(1)).findInRange(eq(150), eq(15), eq(sort), eq(Foo.class)); verify(opsMock, times(1)).findInRange(eq(150L), eq(15), eq(sort), eq(Foo.class));
} }
@Test // DATACMNS-525 @Test // DATACMNS-525

View File

@@ -88,7 +88,7 @@ public class KeyValuePartTreeQueryUnitTests {
KeyValueQuery<?> query = partTreeQuery.prepareQuery(new Object[] { new PageRequest(2, 3) }); KeyValueQuery<?> query = partTreeQuery.prepareQuery(new Object[] { new PageRequest(2, 3) });
assertThat(query.getOffset(), is(6)); assertThat(query.getOffset(), is(6L));
assertThat(query.getRows(), is(3)); assertThat(query.getRows(), is(3));
} }

View File

@@ -31,7 +31,7 @@ import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFa
import org.springframework.data.keyvalue.repository.support.QuerydslKeyValueRepository; import org.springframework.data.keyvalue.repository.support.QuerydslKeyValueRepository;
import org.springframework.data.map.QuerydslKeyValueRepositoryUnitTests.QPersonRepository; import org.springframework.data.map.QuerydslKeyValueRepositoryUnitTests.QPersonRepository;
import org.springframework.data.querydsl.QSort; import org.springframework.data.querydsl.QSort;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -164,5 +164,5 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
} }
static interface QPersonRepository extends org.springframework.data.map.AbstractRepositoryUnitTests.PersonRepository, static interface QPersonRepository extends org.springframework.data.map.AbstractRepositoryUnitTests.PersonRepository,
QueryDslPredicateExecutor<Person> {} QuerydslPredicateExecutor<Person> {}
} }