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

@@ -67,7 +67,7 @@ public class PageAndSliceTests {
assertEquals(10, page3.getNumberOfElements());
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = UnsupportedOperationException.class)
public void shouldThrowWhenPageableIsNullInPageQuery() {
repository.findByAgeGreaterThan(9, null);
}
@@ -86,7 +86,7 @@ public class PageAndSliceTests {
assertEquals(9, allMatching.size());
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = UnsupportedOperationException.class)
public void shouldThrowWhenPageableIsNullSliceQuery() {
repository.findByAgeLessThan(9, null);
}

View File

@@ -2,10 +2,12 @@ package org.springframework.data.couchbase.repository;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.JsonDocument;
@@ -25,6 +27,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Simon Baslé
* @author Mark Paluch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
@@ -50,9 +53,8 @@ public class QueryDerivationConversionTests {
@Test
public void testConvertsDateParameterInN1qlQuery() {
Party partyApril = repository.findOne("testparty-3");
assertNotNull(partyApril);
System.out.println(partyApril);
Optional<Party> partyApril = repository.findOne("testparty-3");
assertTrue(partyApril.isPresent());
Calendar cal = Calendar.getInstance();
cal.clear();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -49,6 +49,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
@@ -56,6 +57,7 @@ import static org.junit.Assert.*;
/**
* @author Michael Nitschinger
* @author Mark Paluch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
@@ -97,14 +99,18 @@ public class SimpleCouchbaseRepositoryTests {
User instance = new User(key, "foobar", 22);
repository.save(instance);
User found = repository.findOne(key);
assertEquals(instance.getKey(), found.getKey());
assertEquals(instance.getUsername(), found.getUsername());
Optional<User> found = repository.findOne(key);
assertTrue(found.isPresent());
assertTrue(repository.exists(key));
repository.delete(found);
found.ifPresent(actual -> {
assertEquals(instance.getKey(), actual.getKey());
assertEquals(instance.getUsername(), actual.getUsername());
assertNull(repository.findOne(key));
assertTrue(repository.exists(key));
repository.delete(actual);
});
assertFalse(repository.findOne(key).isPresent());
assertFalse(repository.exists(key));
}
@@ -214,20 +220,26 @@ public class SimpleCouchbaseRepositoryTests {
versionedDataRepository.save(initial);
assertNotEquals(0L, initial.version);
VersionedData fetch1 = versionedDataRepository.findOne(key);
assertNotSame(initial, fetch1);
assertEquals(fetch1.version, initial.version);
Optional<VersionedData> fetch1 = versionedDataRepository.findOne(key);
assertTrue(fetch1.isPresent());
fetch1.ifPresent(actual -> {
assertNotSame(initial, actual);
assertEquals(actual.version, initial.version);
});
VersionedData versionedData = fetch1.get();
JsonDocument bypass = client.get(key);
bypass.content().put("data", "BBBB");
JsonDocument bypassed = client.upsert(bypass);
assertNotEquals(bypassed.cas(), fetch1.version);
assertNotEquals(bypassed.cas(), versionedData.version);
System.out.println(bypassed.cas());
try {
fetch1.setData("ZZZZ");
versionedDataRepository.save(fetch1);
versionedData.setData("ZZZZ");
versionedDataRepository.save(versionedData);
fail("Expected CAS failure");
} catch (OptimisticLockingFailureException e) {
//success
@@ -255,7 +267,7 @@ public class SimpleCouchbaseRepositoryTests {
boolean updated = false;
while(!updated) {
long counterValue = counter.incrementAndGet();
VersionedData messageData = versionedDataRepository.findOne(key);
VersionedData messageData = versionedDataRepository.findOne(key).get();
messageData.data = "value-" + counterValue;
try {
versionedDataRepository.save(messageData);
@@ -269,7 +281,7 @@ public class SimpleCouchbaseRepositoryTests {
};
AsyncUtils.executeConcurrently(5, task);
assertNotEquals(initial.data, versionedDataRepository.findOne(key).data);
assertNotEquals(initial.data, versionedDataRepository.findOne(key).get().data);
assertEquals(5, updatedCounter.intValue());
}

View File

@@ -1,18 +1,19 @@
package org.springframework.data.couchbase.repository.auditing;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import java.util.Optional;
public class AuditedAuditorAware implements AuditorAware<String> {
private String auditor = "auditor";
private Optional<String> auditor = Optional.of("auditor");
@Override
public String getCurrentAuditor() {
public Optional<String> getCurrentAuditor() {
return auditor;
}
public void setAuditor(String auditor) {
this.auditor = auditor;
this.auditor = Optional.of(auditor);
}
}

View File

@@ -3,19 +3,19 @@ package org.springframework.data.couchbase.repository.auditing;
import static org.junit.Assert.*;
import java.util.Date;
import java.util.Optional;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Simon Baslé
* @author Mark Paluch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AuditedApplicationConfig.class)
@@ -42,20 +42,24 @@ public class AuditingTests {
auditorAware.setAuditor("auditor");
repository.save(item);
AuditedItem persisted = repository.findOne(KEY);
Optional<AuditedItem> persisted = repository.findOne(KEY);
assertNotNull("expected entity to be persisted", persisted);
assertNotNull("expected creation date audit trail", persisted.getCreationDate());
assertEquals("expected creation user audit trail", "auditor", persisted.getCreator());
assertTrue(persisted.isPresent());
assertTrue("creation date is too early", persisted.getCreationDate().after(start));
assertTrue("creation date is too late", persisted.getCreationDate().before(new Date()));
persisted.ifPresent(actual -> {
assertNull("expected modification date to be empty", persisted.getLastModification());
assertNull("expected modification user to be empty", persisted.getLastModifiedBy());
assertNotNull("expected creation date audit trail", actual.getCreationDate());
assertEquals("expected creation user audit trail", "auditor", actual.getCreator());
assertNotNull("expected version to be non null", persisted.getVersion());
assertTrue("expected version to be greater than 0", persisted.getVersion() > 0L);
assertTrue("creation date is too early", actual.getCreationDate().after(start));
assertTrue("creation date is too late", actual.getCreationDate().before(new Date()));
assertNull("expected modification date to be empty", actual.getLastModification());
assertNull("expected modification user to be empty", actual.getLastModifiedBy());
assertNotNull("expected version to be non null", actual.getVersion());
assertTrue("expected version to be greater than 0", actual.getVersion() > 0L);
});
}
@Test
@@ -68,11 +72,11 @@ public class AuditingTests {
auditorAware.setAuditor(expectedCreator);
repository.save(item);
AuditedItem created = repository.findOne(KEY);
AuditedItem created = repository.findOne(KEY).orElse(null);
auditorAware.setAuditor(expectedUpdater);
repository.save(item);
AuditedItem updated = repository.findOne(KEY);
AuditedItem updated = repository.findOne(KEY).orElse(null);
assertNotNull("expected entity to be persisted", updated);
assertNotNull("expected creation date audit trail", updated.getCreationDate());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 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 static org.junit.Assert.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.view.DefaultView;
@@ -89,10 +90,12 @@ public class CdiRepositoryTests {
assertTrue(repository.exists(bean.getId()));
Person retrieved = repository.findOne(bean.getId());
assertNotNull(retrieved);
assertEquals(bean.getName(), retrieved.getName());
assertEquals(bean.getId(), retrieved.getId());
Optional<Person> retrieved = repository.findOne(bean.getId());
assertTrue(retrieved.isPresent());
retrieved.ifPresent(actual -> {
assertEquals(bean.getName(), actual.getName());
assertEquals(bean.getId(), actual.getId());
});
}
/**
@@ -109,10 +112,12 @@ public class CdiRepositoryTests {
assertTrue(qualifiedPersonRepository.exists(bean.getId()));
Person retrieved = qualifiedPersonRepository.findOne(bean.getId());
assertNotNull(retrieved);
assertEquals(bean.getName(), retrieved.getName());
assertEquals(bean.getId(), retrieved.getId());
Optional<Person> retrieved = qualifiedPersonRepository.findOne(bean.getId());
assertTrue(retrieved.isPresent());
retrieved.ifPresent(actual -> {
assertEquals(bean.getName(), actual.getName());
assertEquals(bean.getId(), actual.getId());
});
}
/**

View File

@@ -29,7 +29,7 @@ public class MyRepositoryImpl implements MyRepositoryCustom {
CouchbasePersistentEntity<Object> itemPersistenceEntity = (CouchbasePersistentEntity<Object>)
template.getConverter()
.getMappingContext()
.getPersistentEntity(MyItem.class);
.getRequiredPersistentEntity(MyItem.class);
CouchbaseEntityInformation<? extends Object, String> itemEntityInformation =
new MappingCouchbaseEntityInformation<Object, String>(itemPersistenceEntity);

View File

@@ -5,6 +5,7 @@ import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import com.couchbase.client.java.cluster.ClusterInfo;
import com.couchbase.client.java.util.features.CouchbaseFeature;
@@ -33,6 +34,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* underlying {@link CouchbaseOperations} beans.
*
* @author Simon Baslé
* @author Mark Paluch
*/
@SuppressWarnings("SpringJavaAutowiringInspection")
@RunWith(SpringJUnit4ClassRunner.class)
@@ -128,13 +130,15 @@ public class RepositoryTemplateWiringTests {
boolean existA = repositoryA.exists("testA");
boolean existB = repositoryB.exists("testB");
Misc valueC = repositoryC.findOne("toto");
Optional<Misc> valueC = repositoryC.findOne("toto");
assertTrue(existA);
assertFalse(existB);
assertNotNull(valueC);
assertEquals("mock", valueC.id);
assertEquals(true, valueC.random);
assertTrue(valueC.isPresent());
valueC.ifPresent(actual -> {
assertEquals("mock", actual.id);
assertEquals(true, actual.random);
});
verify(mockOpsA).exists("testA");
verify(mockOpsB).exists("testB");

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -18,15 +18,15 @@ package org.springframework.data.couchbase.core.mapping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Field;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.annotation.Id;
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.data.util.ClassTypeInformation;
@@ -36,6 +36,7 @@ import org.springframework.util.ReflectionUtils;
* Verifies the correct behavior of properties on persistable objects.
*
* @author Michael Nitschinger
* @author Mark Paluch
*/
public class BasicCouchbasePersistentPropertyTests {
@@ -50,7 +51,7 @@ public class BasicCouchbasePersistentPropertyTests {
@Before
public void setUp() {
entity = new BasicCouchbasePersistentEntity<Beer>(
ClassTypeInformation.from(Beer.class));
ClassTypeInformation.from(Beer.class));
}
/**
@@ -74,7 +75,7 @@ public class BasicCouchbasePersistentPropertyTests {
@Test
public void testPrefersSpringIdAnnotation() {
BasicCouchbasePersistentEntity<Beer> test = new BasicCouchbasePersistentEntity<Beer>(
ClassTypeInformation.from(Beer.class));
ClassTypeInformation.from(Beer.class));
Field sdkIdField = ReflectionUtils.findField(Beer.class, "sdkId");
CouchbasePersistentProperty sdkIdProperty = getPropertyFor(sdkIdField);
@@ -89,24 +90,32 @@ public class BasicCouchbasePersistentPropertyTests {
assertTrue(sdkIdProperty.isIdProperty());
assertTrue(springIdProperty.isIdProperty());
assertEquals(springIdProperty, test.getIdProperty());
Optional<CouchbasePersistentProperty> property = test.getIdProperty();
assertTrue(property.isPresent());
property.ifPresent(actual -> {
assertEquals(springIdProperty, actual);
});
}
@Test
public void testAcceptsSdkIdAnnotation() {
BasicCouchbasePersistentEntity<SdkIdentified> test = new BasicCouchbasePersistentEntity<SdkIdentified>(
ClassTypeInformation.from(SdkIdentified.class));
ClassTypeInformation.from(SdkIdentified.class));
Field id = ReflectionUtils.findField(SdkIdentified.class, "id");
CouchbasePersistentProperty idProperty = getPropertyFor(id);
test.addPersistentProperty(idProperty);
assertEquals(idProperty, test.getIdProperty());
Optional<CouchbasePersistentProperty> property = test.getIdProperty();
assertTrue(property.isPresent());
property.ifPresent(actual -> {
assertEquals(idProperty, actual);
});
}
@Test
public void testSdkIdAnnotationEvaluatedAfterSpringIdAnnotationIsIgnored() {
BasicCouchbasePersistentEntity<Beer> test = new BasicCouchbasePersistentEntity<Beer>(
ClassTypeInformation.from(Beer.class));
ClassTypeInformation.from(Beer.class));
Field sdkIdField = ReflectionUtils.findField(Beer.class, "sdkId");
CouchbasePersistentProperty sdkIdProperty = getPropertyFor(sdkIdField);
Field springIdField = ReflectionUtils.findField(Beer.class, "springId");
@@ -115,9 +124,20 @@ public class BasicCouchbasePersistentPropertyTests {
//here this simulates the order in which the annotations would be found
// when "overriding" Spring @Id with SDK's @Id...
test.addPersistentProperty(springIdProperty);
assertEquals(springIdProperty, test.getIdProperty());
Optional<CouchbasePersistentProperty> property = test.getIdProperty();
assertTrue(property.isPresent());
property.ifPresent(actual -> {
assertEquals(springIdProperty, actual);
});
test.addPersistentProperty(sdkIdProperty);
assertEquals(springIdProperty, test.getIdProperty());
property = test.getIdProperty();
assertTrue(property.isPresent());
property.ifPresent(actual -> {
assertEquals(springIdProperty, actual);
});
}
/**
@@ -127,8 +147,8 @@ public class BasicCouchbasePersistentPropertyTests {
* @return the actual BasicCouchbasePersistentProperty instance.
*/
private CouchbasePersistentProperty getPropertyFor(Field field) {
return new BasicCouchbasePersistentProperty(field, null, entity,
new SimpleTypeHolder(), PropertyNameFieldNamingStrategy.INSTANCE);
return new BasicCouchbasePersistentProperty(Property.of(field), entity, new SimpleTypeHolder(),
PropertyNameFieldNamingStrategy.INSTANCE);
}
/**

View File

@@ -8,6 +8,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.springframework.data.couchbase.core.BeerDTO;
@@ -60,6 +61,7 @@ public class PartTreeN1qBasedQueryTest {
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext);
when(accessor.getSort()).thenReturn(Sort.unsorted());
when(entityInformation.getJavaType()).thenReturn(Beer.class);
when(couchbaseOperations.getCouchbaseBucket()).thenReturn(couchbaseBucket);
when(couchbaseBucket.name()).thenReturn("default");
@@ -139,9 +141,8 @@ public class PartTreeN1qBasedQueryTest {
RepositoryMetadata metadata = new DefaultRepositoryMetadata(TestRepository.class);
Method method = TestRepository.class.getMethod("findAllProjectedBy");
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext);
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(accessor);
when(accessor.getDynamicProjection()).thenReturn(Optional.of(BeerProjection.class));
when(entityInformation.getJavaType()).thenReturn(Beer.class);
when(couchbaseOperations.getCouchbaseBucket()).thenReturn(couchbaseBucket);
when(couchbaseBucket.name()).thenReturn("B");
@@ -150,6 +151,8 @@ public class PartTreeN1qBasedQueryTest {
when(couchbaseConverter.getTypeKey()).thenReturn("_class");
when(couchbaseConverter.convertForWriteIfNeeded(eq("value"))).thenReturn("value");
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(Optional.of(accessor));
PartTreeN1qlBasedQuery query = new PartTreeN1qlBasedQuery(queryMethod, couchbaseOperations);
Statement statement = query.getStatement(accessor, null, processor.getReturnedType());
@@ -171,8 +174,8 @@ public class PartTreeN1qBasedQueryTest {
Method method = TestRepository.class.getMethod("findAllDtoedBy");
MappingContext mappingContext = new CouchbaseMappingContext();
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext);
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(accessor);
when(accessor.getDynamicProjection()).thenReturn(Optional.of(BeerDTO.class));
when(entityInformation.getJavaType()).thenReturn(Beer.class);
when(couchbaseOperations.getCouchbaseBucket()).thenReturn(couchbaseBucket);
when(couchbaseBucket.name()).thenReturn("B");
@@ -180,6 +183,8 @@ public class PartTreeN1qBasedQueryTest {
when(couchbaseOperations.getConverter().getMappingContext()).thenReturn(mappingContext);
when(couchbaseConverter.getTypeKey()).thenReturn("_class");
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(Optional.of(accessor));
PartTreeN1qlBasedQuery query = new PartTreeN1qlBasedQuery(queryMethod, couchbaseOperations);
Statement statement = query.getStatement(accessor, null, processor.getReturnedType());