DATACOUCH-273 - Integrate Data Commons Java 8 upgrade branch.

Replace PersistentEntity.doWithProperties(…) and .doWithAssociations(…) with stream processing using PersistentEntity.getPersistentProperties() and PersistentEntity.getAssociations().
This commit is contained in:
Mark Paluch
2017-02-03 12:02:52 +01:00
parent b1e619fec0
commit 141dbefd3d
34 changed files with 365 additions and 271 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@@ -86,6 +87,7 @@ import static org.springframework.data.couchbase.core.support.TemplateUtils.SELE
* @author Oliver Gierke
* @author Simon Baslé
* @author Young-Gu Chae
* @author Mark Paluch
*/
public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventPublisherAware {
@@ -290,7 +292,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
@Override
public <T> T findById(final String id, Class<T> entityClass) {
final CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
final CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(entityClass);
RawJsonDocument result = execute(new BucketCallback<RawJsonDocument>() {
@Override
public RawJsonDocument doInBucket() {
@@ -573,9 +575,9 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
ensureNotIterable(objectToPersist);
final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToPersist);
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(objectToPersist.getClass());
final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null;
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(objectToPersist.getClass());
final Optional<CouchbasePersistentProperty> versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty.flatMap(p -> accessor.getProperty(p, Long.class)).orElse(null);
maybeEmitEvent(new BeforeConvertEvent<Object>(objectToPersist));
final CouchbaseDocument converted = new CouchbaseDocument();
@@ -588,7 +590,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
Document<String> doc = encodeAndWrap(converted, version);
Document<String> storedDoc;
//We will check version only if required
boolean versionPresent = versionProperty != null;
boolean versionPresent = versionProperty.isPresent();
//If version is not set - assumption that document is new, otherwise updating
boolean existingDocument = version != null && version > 0L;
try {
@@ -614,9 +616,9 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
break;
}
if (persistentEntity.hasVersionProperty() && storedDoc != null && storedDoc.cas() != 0) {
if (storedDoc != null && storedDoc.cas() != 0) {
//inject new cas into the bean
accessor.setProperty(versionProperty, storedDoc.cas());
versionProperty.ifPresent(p -> accessor.setProperty(p, Optional.ofNullable(storedDoc.cas())));
return true;
}
return false;
@@ -685,16 +687,14 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
Object readEntity = converter.read(entityClass, (CouchbaseDocument) decodeAndUnwrap(data, converted));
final ConvertingPropertyAccessor accessor = getPropertyAccessor(readEntity);
CouchbasePersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass());
if (persistentEntity.hasVersionProperty()) {
accessor.setProperty(persistentEntity.getVersionProperty(), data.cas());
}
CouchbasePersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(readEntity.getClass());
persistentEntity.getVersionProperty().ifPresent(p -> accessor.setProperty(p, Optional.ofNullable(data.cas())));
return (T) readEntity;
}
private final ConvertingPropertyAccessor getPropertyAccessor(Object source) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass());
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(source.getClass());
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source);
return new ConvertingPropertyAccessor(accessor, converter.getConversionService());

View File

@@ -19,6 +19,7 @@ package org.springframework.data.couchbase.core;
import static org.springframework.data.couchbase.core.CouchbaseTemplate.ensureNotIterable;
import java.util.Collection;
import java.util.Optional;
import com.couchbase.client.java.AsyncBucket;
import com.couchbase.client.java.Bucket;
@@ -47,6 +48,7 @@ import rx.Observable;
/**
* RxJavaCouchbaseTemplate implements operations using rxjava1 observables
* @author Subhashni Balakrishnan
* @author Mark Paluch
* @since 3.0
*/
public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
@@ -149,7 +151,7 @@ public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
}
private final ConvertingPropertyAccessor getPropertyAccessor(Object source) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass());
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(source.getClass());
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source);
return new ConvertingPropertyAccessor(accessor, converter.getConversionService());
@@ -160,9 +162,9 @@ public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
ensureNotIterable(objectToPersist);
final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToPersist);
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(objectToPersist.getClass());
final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null;
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(objectToPersist.getClass());
Optional<CouchbasePersistentProperty> versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty.flatMap(p -> accessor.getProperty(p, Long.class)).orElse(null);
final CouchbaseDocument converted = new CouchbaseDocument();
converter.write(objectToPersist, converted);
@@ -180,9 +182,9 @@ public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
.doOnError(e -> TemplateUtils.translateError(e));
} else {
final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToRemove);
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(objectToRemove.getClass());
final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null;
final CouchbasePersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(objectToRemove.getClass());
final Optional<CouchbasePersistentProperty> versionProperty = persistentEntity.getVersionProperty();
final Long version = versionProperty.flatMap(p -> accessor.getProperty(p, Long.class)).orElse(null);
final CouchbaseDocument converted = new CouchbaseDocument();
converter.write(objectToRemove, converted);
@@ -220,7 +222,7 @@ public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
@Override
public <T> Observable<T> findById(String id, Class<T> entityClass) {
final CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
final CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(entityClass);
if (entity.isTouchOnRead()) {
return client.getAndTouch(id, entity.getExpiry(), RawJsonDocument.class)
.switchIfEmpty(Observable.just(null))
@@ -336,10 +338,8 @@ public class RxJavaCouchbaseTemplate implements RxJavaCouchbaseOperations {
Object readEntity = converter.read(entityClass, (CouchbaseDocument) decodeAndUnwrap(data, converted));
final ConvertingPropertyAccessor accessor = getPropertyAccessor(readEntity);
CouchbasePersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass());
if (persistentEntity.hasVersionProperty()) {
accessor.setProperty(persistentEntity.getVersionProperty(), data.cas());
}
CouchbasePersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(readEntity.getClass());
persistentEntity.getVersionProperty().ifPresent(p -> accessor.setProperty(p, Optional.ofNullable(data.cas())));
return (T) readEntity;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -19,11 +19,15 @@ package org.springframework.data.couchbase.core.convert;
import org.springframework.data.convert.DefaultTypeMapper;
import org.springframework.data.convert.TypeAliasAccessor;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.mapping.Alias;
import java.util.Optional;
/**
* The Couchbase Type Mapper.
*
* @author Michael Nitschinger
* @author Mark Paluch
*/
public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocument> implements CouchbaseTypeMapper {
@@ -58,8 +62,8 @@ public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocum
}
@Override
public Object readAliasFrom(final CouchbaseDocument source) {
return source.get(typeKey);
public Alias readAliasFrom(final CouchbaseDocument source) {
return Alias.ofOptional(Optional.ofNullable(source.get(typeKey)));
}
@Override

View File

@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.couchbase.client.java.repository.annotation.Field;
@@ -201,10 +202,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
return (R) readMap(typeToUse, source, parent);
}
CouchbasePersistentEntity<R> entity = (CouchbasePersistentEntity<R>) mappingContext.getPersistentEntity(typeToUse);
if (entity == null) {
throw new MappingException("No mapping metadata found for " + rawType.getName());
}
CouchbasePersistentEntity<R> entity = (CouchbasePersistentEntity<R>) mappingContext.getRequiredPersistentEntity(typeToUse);
return read(entity, source, parent);
}
@@ -226,30 +224,27 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
final R instance = instantiator.createInstance(entity, provider);
final ConvertingPropertyAccessor accessor = getPropertyAccessor(instance);
entity.doWithProperties(new PropertyHandler<CouchbasePersistentProperty>() {
@Override
public void doWithPersistentProperty(final CouchbasePersistentProperty prop) {
if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop)) {
return;
}
Object obj = prop.isIdProperty() ? source.getId() : getValueInternal(prop, source, instance);
accessor.setProperty(prop, obj);
entity.getPersistentProperties().filter(prop -> {
if (!(prop.isIdProperty() || source.containsKey(prop.getFieldName())) || entity.isConstructorArgument(prop)) {
return false;
}
private boolean doesPropertyExistInSource(final CouchbasePersistentProperty property) {
return property.isIdProperty() || source.containsKey(property.getFieldName());
}
return true;
}).forEach(prop -> {
Optional<Object> obj = prop.isIdProperty() ? Optional.ofNullable(source.getId()) : getValueInternal(prop, source, instance);
accessor.setProperty(prop, obj);
});
entity.doWithAssociations(new AssociationHandler<CouchbasePersistentProperty>() {
@Override
public void doWithAssociation(final Association<CouchbasePersistentProperty> association) {
CouchbasePersistentProperty inverseProp = association.getInverse();
Object obj = getValueInternal(inverseProp, source, instance);
accessor.setProperty(inverseProp, obj);
}
entity.getAssociations().forEach(association -> {
CouchbasePersistentProperty inverseProp = association.getInverse();
Optional<Object> obj = getValueInternal(inverseProp, source, instance);
accessor.setProperty(inverseProp, obj);
});
return instance;
}
@@ -261,7 +256,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @param parent the optional parent.
* @return the actual property value.
*/
protected Object getValueInternal(final CouchbasePersistentProperty property, final CouchbaseDocument source,
protected Optional<Object> getValueInternal(final CouchbasePersistentProperty property, final CouchbaseDocument source,
final Object parent) {
return new CouchbasePropertyValueProvider(source, spELContext, parent).getPropertyValue(property);
}
@@ -280,7 +275,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
CouchbasePropertyValueProvider provider = new CouchbasePropertyValueProvider(source, evaluator, parent);
PersistentEntityParameterValueProvider<CouchbasePersistentProperty> parameterProvider =
new PersistentEntityParameterValueProvider<CouchbasePersistentProperty>(entity, provider, parent);
new PersistentEntityParameterValueProvider<CouchbasePersistentProperty>(entity, provider, Optional.ofNullable(parent));
return new ConverterAwareSpELExpressionParameterValueProvider(evaluator, conversionService, parameterProvider,
parent);
@@ -304,16 +299,13 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
Map<String, Object> sourceMap = source.getPayload();
for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
TypeInformation<?> keyTypeInformation = type.getComponentType();
if (keyTypeInformation != null) {
Class<?> keyType = keyTypeInformation.getType();
key = conversionService.convert(key, keyType);
}
Object key = type.getComponentType().map(TypeInformation::getType) //
.map(keyType -> (Object) conversionService.convert(entry.getKey(), keyType)) //
.orElse(entry.getKey());
TypeInformation<?> valueType = type.getMapValueType();
TypeInformation<?> valueType = type.getMapValueType().orElse(null);
if (value instanceof CouchbaseDocument) {
map.put(key, read(valueType, (CouchbaseDocument) value, parent));
} else if (value instanceof CouchbaseList) {
@@ -406,7 +398,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
throw new IllegalArgumentException("Root Document must be either CouchbaseDocument or Map.");
}
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass());
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass()).orElse(null);
writeInternal(source, target, entity);
addCustomTypeKeyIfNecessary(typeHint, source, target);
}
@@ -443,45 +435,49 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
}
final ConvertingPropertyAccessor accessor = getPropertyAccessor(source);
final CouchbasePersistentProperty idProperty = entity.getIdProperty();
final CouchbasePersistentProperty versionProperty = entity.getVersionProperty();
final Optional<CouchbasePersistentProperty> idProperty = entity.getIdProperty();
final Optional<CouchbasePersistentProperty> versionProperty = entity.getVersionProperty();
if (idProperty != null && target.getId() == null) {
String id = accessor.getProperty(idProperty, String.class);
target.setId(id);
if (target.getId() == null) {
idProperty.ifPresent(id -> {
target.setId(accessor.getProperty(id, String.class).orElse(null));
});
}
target.setExpiration(entity.getExpiry());
entity.doWithProperties(new PropertyHandler<CouchbasePersistentProperty>() {
@Override
public void doWithPersistentProperty(final CouchbasePersistentProperty prop) {
if (prop.equals(idProperty) || (versionProperty != null && prop.equals(versionProperty))) {
return;
} else if(enableStrictFieldChecking && !prop.isAnnotationPresent(Field.class)){
return;
}
entity.getPersistentProperties().filter(prop -> {
Object propertyObj = accessor.getProperty(prop, prop.getType());
if (null != propertyObj) {
if (!conversions.isSimpleType(propertyObj.getClass())) {
writePropertyInternal(propertyObj, target, prop);
} else {
writeSimpleInternal(propertyObj, target, prop.getFieldName());
}
}
if (idProperty.filter(prop::equals).isPresent()) {
return false;
}
if (versionProperty.filter(prop::equals).isPresent()) {
return false;
}
if (enableStrictFieldChecking && !prop.isAnnotationPresent(Field.class)) {
return false;
}
return true;
}).forEach(prop -> {
Optional<Object> propertyObj = accessor.getProperty(prop, (Class) prop.getType());
propertyObj.ifPresent(o -> {
if (!conversions.isSimpleType(o.getClass())) {
writePropertyInternal(o, target, prop);
} else {
writeSimpleInternal(o, target, prop.getFieldName());
}
});
});
entity.doWithAssociations(new AssociationHandler<CouchbasePersistentProperty>() {
@Override
public void doWithAssociation(final Association<CouchbasePersistentProperty> association) {
CouchbasePersistentProperty inverseProp = association.getInverse();
Class<?> type = inverseProp.getType();
Object propertyObj = accessor.getProperty(inverseProp, type);
if (null != propertyObj) {
writePropertyInternal(propertyObj, target, inverseProp);
}
}
entity.getAssociations().forEach(association -> {
CouchbasePersistentProperty inverseProp = association.getInverse();
Class<?> type = inverseProp.getType();
Optional<Object> propertyObj = accessor.getProperty(inverseProp, (Class) type);
propertyObj.ifPresent(o -> {
writePropertyInternal(o, target, inverseProp);
});
});
}
@@ -526,7 +522,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
addCustomTypeKeyIfNecessary(type, source, propertyDoc);
CouchbasePersistentEntity<?> entity = isSubtype(prop.getType(), source.getClass()) ? mappingContext
.getPersistentEntity(source.getClass()) : mappingContext.getPersistentEntity(type);
.getRequiredPersistentEntity(source.getClass()) : mappingContext.getRequiredPersistentEntity(type);
writeInternal(source, propertyDoc, entity);
target.put(name, propertyDoc);
}
@@ -568,7 +564,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
target.put(simpleKey, writeCollectionInternal(asCollection(val), new CouchbaseList(conversions.getSimpleTypeHolder()), type.getMapValueType()));
} else {
CouchbaseDocument embeddedDoc = new CouchbaseDocument();
TypeInformation<?> valueTypeInfo = type.isMap() ? type.getMapValueType() : ClassTypeInformation.OBJECT;
TypeInformation<?> valueTypeInfo = type.isMap() ? type.getMapValueType().orElse(ClassTypeInformation.OBJECT) : ClassTypeInformation.OBJECT;
writeInternal(val, embeddedDoc, valueTypeInfo);
target.put(simpleKey, embeddedDoc);
}
@@ -588,7 +584,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return the created couchbase list.
*/
private CouchbaseList createCollection(final Collection<?> collection, final CouchbasePersistentProperty prop) {
return writeCollectionInternal(collection, new CouchbaseList(conversions.getSimpleTypeHolder()), prop.getTypeInformation());
return writeCollectionInternal(collection, new CouchbaseList(conversions.getSimpleTypeHolder()), Optional.of(prop.getTypeInformation()));
}
/**
@@ -600,8 +596,9 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return the created couchbase list.
*/
private CouchbaseList writeCollectionInternal(final Collection<?> source, final CouchbaseList target,
final TypeInformation<?> type) {
TypeInformation<?> componentType = type == null ? null : type.getComponentType();
final Optional<TypeInformation<?>> type) {
Optional<TypeInformation<?>> componentType = type.flatMap(TypeInformation::getComponentType);
for (Object element : source) {
Class<?> elementType = element == null ? null : element.getClass();
@@ -611,8 +608,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
} else if (element instanceof Collection || elementType.isArray()) {
target.put(writeCollectionInternal(asCollection(element), new CouchbaseList(conversions.getSimpleTypeHolder()), componentType));
} else {
TypeInformation<?> typeInformation = componentType.orElse(null);
CouchbaseDocument embeddedDoc = new CouchbaseDocument();
writeInternal(element, embeddedDoc, componentType);
writeInternal(element, embeddedDoc, typeInformation);
target.put(embeddedDoc);
}
@@ -641,7 +640,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory
.createCollection(collectionType, source.size(false));
TypeInformation<?> componentType = targetType.getComponentType();
TypeInformation<?> componentType = targetType.getComponentType().orElse(null);
Class<?> rawComponentType = componentType == null ? null : componentType.getType();
for (int i = 0; i < source.size(false); i++) {
@@ -756,7 +755,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
}
private ConvertingPropertyAccessor getPropertyAccessor(Object source) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass());
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(source.getClass());
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source);
return new ConvertingPropertyAccessor(accessor, conversionService);
@@ -799,18 +798,18 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
@Override
@SuppressWarnings("unchecked")
public <R> R getPropertyValue(final CouchbasePersistentProperty property) {
String expression = property.getSpelExpression();
Object value = expression != null ? evaluator.evaluate(expression) : source.get(property.getFieldName());
public <R> Optional<R> getPropertyValue(final CouchbasePersistentProperty property) {
Object value = property.getSpelExpression().map(evaluator::evaluate).orElseGet(() -> source.get(property.getFieldName()));
if (property.isIdProperty()) {
return (R) source.getId();
return Optional.ofNullable((R) source.getId());
}
if (value == null) {
return null;
return Optional.empty();
}
return readValue(value, property.getTypeInformation(), parent);
return Optional.ofNullable(readValue(value, property.getTypeInformation(), parent));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -32,9 +32,10 @@ import java.util.concurrent.TimeUnit;
* The representation of a persistent entity.
*
* @author Michael Nitschinger
* @author Mark Paluch
*/
public class BasicCouchbasePersistentEntity<T> extends BasicPersistentEntity<T, CouchbasePersistentProperty>
implements CouchbasePersistentEntity<T>, EnvironmentAware {
implements CouchbasePersistentEntity<T>, EnvironmentAware {
private Environment environment;
@@ -74,8 +75,12 @@ public class BasicCouchbasePersistentEntity<T> extends BasicPersistentEntity<T,
}
//check existing ID vs new candidate
boolean currentCbId = this.getIdProperty().isAnnotationPresent(Id.class);
boolean currentSpringId = this.getIdProperty().isAnnotationPresent(org.springframework.data.annotation.Id.class);
boolean currentCbId = this.getIdProperty()
.map(couchbasePersistentProperty -> couchbasePersistentProperty.isAnnotationPresent(Id.class))
.orElse(false);
boolean currentSpringId = this.getIdProperty()
.map(couchbasePersistentProperty -> couchbasePersistentProperty.isAnnotationPresent(org.springframework.data.annotation.Id.class))
.orElse(false);
boolean candidateCbId = property.isAnnotationPresent(Id.class);
boolean candidateSpringId = property.isAnnotationPresent(org.springframework.data.annotation.Id.class);
@@ -137,7 +142,7 @@ public class BasicCouchbasePersistentEntity<T> extends BasicPersistentEntity<T,
@Override
public boolean isTouchOnRead() {
org.springframework.data.couchbase.core.mapping.Document annotation = getType().getAnnotation(
org.springframework.data.couchbase.core.mapping.Document.class);
org.springframework.data.couchbase.core.mapping.Document.class);
return annotation == null ? false : annotation.touchOnRead() && getExpiry() > 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -16,19 +16,19 @@
package org.springframework.data.couchbase.core.mapping;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.util.StringUtils;
import java.util.Optional;
/**
* Implements annotated property representations of a given {@link com.couchbase.client.java.repository.annotation.Field} instance.
* <p/>
@@ -36,27 +36,27 @@ import org.springframework.util.StringUtils;
* supports overriding of the actual property name by providing custom annotations.</p>
*
* @author Michael Nitschinger
* @author Mark Paluch
*/
public class BasicCouchbasePersistentProperty
extends AnnotationBasedPersistentProperty<CouchbasePersistentProperty>
implements CouchbasePersistentProperty {
extends AnnotationBasedPersistentProperty<CouchbasePersistentProperty>
implements CouchbasePersistentProperty {
private final FieldNamingStrategy fieldNamingStrategy;
/**
* Create a new instance of the BasicCouchbasePersistentProperty class.
*
* @param field the field of the original reflection.
* @param propertyDescriptor the PropertyDescriptor.
* @param owner the original owner of the property.
* @param property the PropertyDescriptor.
* @param owner the original owner of the property.
* @param simpleTypeHolder the type holder.
*/
public BasicCouchbasePersistentProperty(final Field field, final PropertyDescriptor propertyDescriptor,
public BasicCouchbasePersistentProperty(Property property,
final CouchbasePersistentEntity<?> owner, final SimpleTypeHolder simpleTypeHolder,
final FieldNamingStrategy fieldNamingStrategy) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
super(property, owner, simpleTypeHolder);
this.fieldNamingStrategy = fieldNamingStrategy == null ? PropertyNameFieldNamingStrategy.INSTANCE
: fieldNamingStrategy;
: fieldNamingStrategy;
}
/**
@@ -75,21 +75,20 @@ public class BasicCouchbasePersistentProperty
*/
@Override
public String getFieldName() {
com.couchbase.client.java.repository.annotation.Field annotation = getField().
getAnnotation(com.couchbase.client.java.repository.annotation.Field.class);
Optional<Field> annotation = findAnnotation(com.couchbase.client.java.repository.annotation.Field.class);
if (annotation != null && StringUtils.hasText(annotation.value())) {
return annotation.value();
}
return annotation.map(Field::value).filter(StringUtils::hasText).orElseGet(() -> {
String fieldName = fieldNamingStrategy.getFieldName(this);
String fieldName = fieldNamingStrategy.getFieldName(this);
if (!StringUtils.hasText(fieldName)) {
throw new MappingException(String.format("Invalid (null or empty) field name returned for property %s by %s!",
this, fieldNamingStrategy.getClass()));
}
if (!StringUtils.hasText(fieldName)) {
throw new MappingException(String.format("Invalid (null or empty) field name returned for property %s by %s!",
this, fieldNamingStrategy.getClass()));
}
return fieldName;
});
return fieldName;
}
// DATACOUCH-145: allows SDK's @Id annotation to be used

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -16,14 +16,12 @@
package org.springframework.data.couchbase.core.mapping;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
@@ -83,16 +81,15 @@ public class CouchbaseMappingContext
/**
* Creates a concrete property based on the field information and entity.
*
* @param field the reflection on the field to be used as a property.
* @param descriptor the property descriptor.
* @param property the property descriptor.
* @param owner the entity which owns the property.
* @param simpleTypeHolder the type holder.
* @return the constructed property.
*/
@Override
protected CouchbasePersistentProperty createPersistentProperty(final Field field, final PropertyDescriptor descriptor,
protected CouchbasePersistentProperty createPersistentProperty(Property property,
final BasicCouchbasePersistentEntity<?> owner, final SimpleTypeHolder simpleTypeHolder) {
return new BasicCouchbasePersistentProperty(field, descriptor, owner, simpleTypeHolder, fieldNamingStrategy);
return new BasicCouchbasePersistentProperty(property, owner, simpleTypeHolder, fieldNamingStrategy);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors
* Copyright 2012-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.
@@ -23,11 +23,14 @@ import org.springframework.data.auditing.IsNewAwareAuditingHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import java.util.Optional;
/**
* Event listener to populate auditing related fields on an entity about to be saved.
*
* @author Oliver Gierke
* @author Simon Baslé
* @author Mark Paluch
*/
public class AuditingEventListener implements ApplicationListener<BeforeConvertEvent<Object>> {
@@ -51,6 +54,6 @@ public class AuditingEventListener implements ApplicationListener<BeforeConvertE
public void onApplicationEvent(BeforeConvertEvent<Object> event) {
Object entity = event.getSource();
auditingHandlerFactory.getObject().markAudited(entity);
auditingHandlerFactory.getObject().markAudited(Optional.of(entity));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
@@ -20,6 +20,7 @@ import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.lang.annotation.Annotation;
import java.util.Optional;
import java.util.Set;
import org.springframework.data.couchbase.core.CouchbaseOperations;
@@ -50,7 +51,7 @@ public class CouchbaseRepositoryBean<T> extends CdiRepositoryBean<T> {
*/
public CouchbaseRepositoryBean(Bean<CouchbaseOperations> operations, Set<Annotation> qualifiers, Class<T> repositoryType,
BeanManager beanManager, CustomRepositoryImplementationDetector detector) {
super(qualifiers, repositoryType, beanManager, detector);
super(qualifiers, repositoryType, beanManager, Optional.of(detector));
Assert.notNull(operations, "Cannot create repository with 'null' for CouchbaseOperations.");
this.couchbaseOperationsBean = operations;
@@ -61,11 +62,17 @@ public class CouchbaseRepositoryBean<T> extends CdiRepositoryBean<T> {
* @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class, java.lang.Object)
*/
@Override
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Object customImplementation) {
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Optional<Object> customImplementation) {
CouchbaseOperations couchbaseOperations = getDependencyInstance(couchbaseOperationsBean, CouchbaseOperations.class);
RepositoryOperationsMapping couchbaseOperationsMapping = new RepositoryOperationsMapping(couchbaseOperations);
IndexManager indexManager = new IndexManager();
return new CouchbaseRepositoryFactory(couchbaseOperationsMapping, indexManager).getRepository(repositoryType, customImplementation);
CouchbaseRepositoryFactory factory =
new CouchbaseRepositoryFactory(couchbaseOperationsMapping, indexManager);
return customImplementation.map(o -> factory.getRepository(repositoryType, o))
.orElseGet(() -> factory.getRepository(repositoryType));
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
@@ -20,6 +20,7 @@ import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.lang.annotation.Annotation;
import java.util.Optional;
import java.util.Set;
import org.springframework.data.couchbase.core.RxJavaCouchbaseOperations;
@@ -33,6 +34,7 @@ import org.springframework.util.Assert;
/**
* A bean which represents a Couchbase repository.
* @author Subhashni Balakrishnan
* @author Mark Paluch
*/
public class ReactiveCouchbaseRepositoryBean<T> extends CdiRepositoryBean<T> {
@@ -50,22 +52,27 @@ public class ReactiveCouchbaseRepositoryBean<T> extends CdiRepositoryBean<T> {
*/
public ReactiveCouchbaseRepositoryBean(Bean<RxJavaCouchbaseOperations> reactiveOperations, Set<Annotation> qualifiers, Class<T> repositoryType,
BeanManager beanManager, CustomRepositoryImplementationDetector detector) {
super(qualifiers, repositoryType, beanManager, detector);
super(qualifiers, repositoryType, beanManager, Optional.of(detector));
Assert.notNull(reactiveOperations, "Cannot create repository with 'null' for ReactiveCouchbaseOperations.");
this.reactiveCouchbaseOperationsBean = reactiveOperations;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class, java.lang.Object)
*/
@Override
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Object customImplementation) {
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Optional<Object> customImplementation) {
RxJavaCouchbaseOperations reactiveCouchbaseOperations = getDependencyInstance(reactiveCouchbaseOperationsBean, RxJavaCouchbaseOperations.class);
ReactiveRepositoryOperationsMapping reactiveCouchbaseOperationsMapping = new ReactiveRepositoryOperationsMapping(reactiveCouchbaseOperations);
IndexManager indexManager = new IndexManager();
return new ReactiveCouchbaseRepositoryFactory(reactiveCouchbaseOperationsMapping, indexManager).getRepository(repositoryType, customImplementation);
ReactiveCouchbaseRepositoryFactory factory = new ReactiveCouchbaseRepositoryFactory(reactiveCouchbaseOperationsMapping, indexManager);
return customImplementation.map(o -> factory.getRepository(repositoryType, o))
.orElseGet(() -> factory.getRepository(repositoryType));
}
@Override

View File

@@ -19,6 +19,7 @@ package org.springframework.data.couchbase.repository.query;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;
@@ -85,7 +86,7 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
public Object execute(Object[] parameters) {
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
ResultProcessor processor = this.queryMethod.getResultProcessor().withDynamicProjection(accessor);
ResultProcessor processor = this.queryMethod.getResultProcessor().withDynamicProjection(Optional.of(accessor));
ReturnedType returnedType = processor.getReturnedType();
Class<?> typeToRead = returnedType.getTypeToRead();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors
* Copyright 2012-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.
@@ -16,6 +16,7 @@
package org.springframework.data.couchbase.repository.query;
import java.util.Iterator;
import java.util.Optional;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.domain.Pageable;
@@ -30,7 +31,7 @@ import com.couchbase.client.java.query.dsl.path.WherePath;
/**
*
* @author Mark Ramach
*
* @author Mark Paluch
*/
public class N1qlCountQueryCreator extends N1qlQueryCreator {
@@ -42,7 +43,7 @@ public class N1qlCountQueryCreator extends N1qlQueryCreator {
@Override
protected LimitPath complete(Expression criteria, Sort sort) {
// Sorting is not allowed on aggregate count queries.
return super.complete(criteria, null);
return super.complete(criteria, Sort.unsorted());
}
private static class CountParameterAccessor implements ParameterAccessor {
@@ -54,14 +55,14 @@ public class N1qlCountQueryCreator extends N1qlQueryCreator {
}
public Pageable getPageable() {
return delegate.getPageable() != null ? new CountPageable(delegate.getPageable()) : null;
return delegate.getPageable() != Pageable.NONE ? new CountPageable(delegate.getPageable()) : Pageable.NONE;
}
public Sort getSort() {
return null;
return Sort.unsorted();
}
public Class<?> getDynamicProjection() {
public Optional<Class<?>> getDynamicProjection() {
return delegate.getDynamicProjection();
}
@@ -95,13 +96,13 @@ public class N1qlCountQueryCreator extends N1qlQueryCreator {
return delegate.getPageSize();
}
public int getOffset() {
public long getOffset() {
return delegate.getOffset();
}
public Sort getSort() {
// Sorting is not allowed on aggregate count queries.
return null;
return Sort.unsorted();
}
public Pageable next() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -88,6 +88,7 @@ import org.springframework.data.repository.query.parser.PartTree;
* </p>
*
* @author Simon Baslé
* @author Mark Paluch
*/
public class N1qlQueryCreator extends AbstractQueryCreator<LimitPath, Expression> {
@@ -131,14 +132,12 @@ public class N1qlQueryCreator extends AbstractQueryCreator<LimitPath, Expression
OrderByPath selectFromWhere = selectFrom.where(whereCriteria);
//sort of the Pageable takes precedence over the sort in the query name
if ((queryMethod.isPageQuery() || queryMethod.isSliceQuery()) && accessor.getPageable() != null) {
if ((queryMethod.isPageQuery() || queryMethod.isSliceQuery()) && !Pageable.NONE.equals(accessor.getPageable())) {
Pageable pageable = accessor.getPageable();
if (pageable.getSort() != null) {
sort = pageable.getSort();
}
}
if (sort != null) {
if (sort.isSorted()) {
com.couchbase.client.java.query.dsl.Sort[] cbSorts = N1qlUtils.createSort(sort, converter);
return selectFromWhere.orderBy(cbSorts);
}

View File

@@ -43,7 +43,6 @@ import org.springframework.util.Assert;
* @author Subhashni Balakrishnan
* @author Mark Paluch
*/
public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
private final PartTree partTree;
@@ -87,11 +86,11 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
if (queryMethod.isPageQuery()) {
Pageable pageable = accessor.getPageable();
Assert.notNull(pageable, "Pageable must not be null!");
return selectFromWhereOrderBy.limit(pageable.getPageSize()).offset(pageable.getOffset());
} else if (queryMethod.isSliceQuery() && accessor.getPageable() != null) {
return selectFromWhereOrderBy.limit(pageable.getPageSize()).offset(Math.toIntExact(pageable.getOffset()));
} else if (queryMethod.isSliceQuery() && accessor.getPageable() != Pageable.NONE) {
Pageable pageable = accessor.getPageable();
Assert.notNull(pageable, "Pageable must not be null!");
return selectFromWhereOrderBy.limit(pageable.getPageSize() + 1).offset(pageable.getOffset());
return selectFromWhereOrderBy.limit(pageable.getPageSize() + 1).offset(Math.toIntExact(pageable.getOffset()));
} else if (partTree.isLimiting()) {
return selectFromWhereOrderBy.limit(partTree.getMaxResults());
} else {

View File

@@ -16,6 +16,8 @@
package org.springframework.data.couchbase.repository.query;
import java.util.Map;
import java.util.Optional;
import com.couchbase.client.java.document.json.JsonValue;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.query.Statement;
@@ -29,6 +31,7 @@ import reactor.core.publisher.Flux;
/**
* @author Subhashni Balakrishnan
* @author Mark Paluch
* @since 3.0
*/
public abstract class ReactiveAbstractN1qlBasedQuery implements RepositoryQuery {
@@ -49,7 +52,7 @@ public abstract class ReactiveAbstractN1qlBasedQuery implements RepositoryQuery
@Override
public Object execute(Object[] parameters) {
ReactiveCouchbaseParameterAccessor accessor = new ReactiveCouchbaseParameterAccessor(queryMethod, parameters);
ResultProcessor processor = this.queryMethod.getResultProcessor().withDynamicProjection(accessor);
ResultProcessor processor = this.queryMethod.getResultProcessor().withDynamicProjection(Optional.of(accessor));
ReturnedType returnedType = processor.getReturnedType();
Class<?> typeToRead = returnedType.getTypeToRead();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -69,6 +69,8 @@ import org.springframework.data.repository.query.parser.PartTree;
* </ul>
* </p>
* Additionally, {@link PartTree#isLimiting()} will trigger usage of {@link SpatialViewQuery#limit(int) limit}.
*
* @author Mark Paluch
*/
public class SpatialViewQueryCreator extends AbstractQueryCreator<SpatialViewQueryCreator.SpatialViewQueryWrapper, SpatialViewQuery> {
@@ -240,7 +242,7 @@ public class SpatialViewQueryCreator extends AbstractQueryCreator<SpatialViewQue
@Override
protected SpatialViewQueryWrapper complete(SpatialViewQuery criteria, Sort sort) {
if (sort != null) {
if (sort.isSorted()) {
throw new IllegalArgumentException("Sort is not supported on Spatial View queries");
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.couchbase.repository.query;
import static org.springframework.data.couchbase.core.support.TemplateUtils.*;
@@ -191,7 +206,7 @@ public class StringBasedN1qlQueryParser {
placeholder = placeholder.replaceFirst(":", "");
namedValues.put(placeholder, value);
} else {
namedValues.put(parameter.getName(), value);
parameter.getName().ifPresent(name -> namedValues.put(name, value));
}
}
return namedValues;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -53,6 +53,7 @@ import org.springframework.util.Assert;
*
* @author Simon Baslé
* @author Subhashni Balakrishnan
* @author Mark Paluch
*/
public class StringN1qlBasedQuery extends AbstractN1qlBasedQuery {
private final SpelExpressionParser parser;
@@ -89,18 +90,20 @@ public class StringN1qlBasedQuery extends AbstractN1qlBasedQuery {
String limitByPart = "";
Sort sort = accessor.getSort();
if (sort != null) {
if (sort.isSorted()) {
com.couchbase.client.java.query.dsl.Sort[] cbSorts = N1qlUtils.createSort(sort, getCouchbaseOperations().getConverter());
orderByPart = " " + new DefaultOrderByPath(null).orderBy(cbSorts).toString();
}
if (queryMethod.isPageQuery()) {
Pageable pageable = accessor.getPageable();
Assert.notNull(pageable);
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize()).offset(pageable.getOffset()).toString();
Assert.notNull(pageable, "Pageable must not be null!");
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize())
.offset(Math.toIntExact(pageable.getOffset())).toString();
} else if (queryMethod.isSliceQuery()) {
Pageable pageable = accessor.getPageable();
Assert.notNull(pageable);
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize() + 1).offset(pageable.getOffset()).toString();
Assert.notNull(pageable, "Pageable must not be null!");
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize() + 1)
.offset(Math.toIntExact(pageable.getOffset())).toString();
}
return N1qlQuery.simple(parsedStatement + orderByPart + limitByPart).statement();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-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.
@@ -275,7 +275,7 @@ public class ViewQueryCreator extends AbstractQueryCreator<ViewQueryCreator.Deri
protected DerivedViewQuery complete(ViewQuery criteria, Sort sort) {
boolean descending = false;
if (sort != null) {
if (sort.isSorted()) {
int sortCount = 0;
Iterator<Sort.Order> it = sort.iterator();
while(it.hasNext()) {

View File

@@ -65,6 +65,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
*
* @author Simon Baslé
* @author Subhashni Balakrishnan
* @author Mark Paluch
*/
public class N1qlUtils {
@@ -107,10 +108,10 @@ public class N1qlUtils {
if (returnedType != null && returnedType.needsCustomConstruction()) {
List<String> properties = returnedType.getInputProperties();
CouchbasePersistentEntity<?> entity = converter.getMappingContext().getPersistentEntity(returnedType.getDomainType());
CouchbasePersistentEntity<?> entity = converter.getMappingContext().getRequiredPersistentEntity(returnedType.getDomainType());
for (String property : properties) {
expList.add(path(bucket, i(entity.getPersistentProperty(property).getFieldName())));
expList.add(path(bucket, i(entity.getRequiredPersistentProperty(property).getFieldName())));
}
} else {
expList.add(path(bucket, "*"));

View File

@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.repository.support;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Optional;
import com.couchbase.client.java.util.features.CouchbaseFeature;
@@ -111,12 +112,8 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
*/
@Override
public <T, ID extends Serializable> CouchbaseEntityInformation<T, ID> getEntityInformation(final Class<T> domainClass) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
if (entity == null) {
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
}
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(domainClass);
return new MappingCouchbaseEntityInformation<T, ID>((CouchbasePersistentEntity<T>) entity);
}
@@ -206,8 +203,8 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
}
@Override
protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider contextProvider) {
return new CouchbaseQueryLookupStrategy(contextProvider);
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider contextProvider) {
return Optional.of(new CouchbaseQueryLookupStrategy(contextProvider));
}
/**

View File

@@ -105,14 +105,14 @@ public class N1qlCouchbaseRepository<T, ID extends Serializable>
//apply the sort if available
LimitPath limitPath = groupBy;
if (pageable.getSort() != null) {
if (pageable.getSort().isSorted()) {
com.couchbase.client.java.query.dsl.Sort[] orderings = N1qlUtils.createSort(pageable.getSort(),
getCouchbaseOperations().getConverter());
limitPath = groupBy.orderBy(orderings);
}
//apply the paging
Statement pageStatement = limitPath.limit(pageable.getPageSize()).offset(pageable.getOffset());
Statement pageStatement = limitPath.limit(pageable.getPageSize()).offset(Math.toIntExact(pageable.getOffset()));
//fire the query
N1qlQuery query = N1qlQuery.simple(pageStatement, N1qlParams.build().consistency(consistency));

View File

@@ -17,6 +17,7 @@ package org.springframework.data.couchbase.repository.support;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Optional;
import com.couchbase.client.java.util.features.CouchbaseFeature;
import org.springframework.core.annotation.AnnotationUtils;
@@ -41,7 +42,8 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;
/**
* @Subhashni Balakrishnan
* @author Subhashni Balakrishnan
* @author Mark Paluch
* @since 3.0
*/
public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactorySupport {
@@ -96,11 +98,7 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
*/
@Override
public <T, ID extends Serializable> CouchbaseEntityInformation<T, ID> getEntityInformation(final Class<T> domainClass) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
if (entity == null) {
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
}
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(domainClass);
return new MappingCouchbaseEntityInformation<T, ID>((CouchbasePersistentEntity<T>) entity);
}
@@ -192,8 +190,8 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
}
@Override
protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider contextProvider) {
return new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(contextProvider);
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider contextProvider) {
return Optional.of(new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(contextProvider));
}
/**

View File

@@ -19,6 +19,7 @@ package org.springframework.data.couchbase.repository.support;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.error.DocumentDoesNotExistException;
@@ -100,9 +101,9 @@ public class SimpleCouchbaseRepository<T, ID extends Serializable> implements Co
}
@Override
public T findOne(ID id) {
public Optional<T> findOne(ID id) {
Assert.notNull(id, "The given id must not be null!");
return couchbaseOperations.findById(id.toString(), entityInformation.getJavaType());
return Optional.ofNullable(couchbaseOperations.findById(id.toString(), entityInformation.getJavaType()));
}
@Override