committed by
Jens Schauder
parent
d96427a035
commit
e92b6b0295
@@ -16,8 +16,7 @@
|
||||
|
||||
package org.springframework.data.couchbase.core.convert;
|
||||
|
||||
import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.UNIQUE;
|
||||
import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.USE_ATTRIBUTES;
|
||||
import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.*;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.lang.reflect.InaccessibleObjectException;
|
||||
@@ -34,10 +33,14 @@ import java.util.UUID;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.EnvironmentCapable;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.data.convert.CustomConversions;
|
||||
import org.springframework.data.convert.PropertyValueConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
@@ -62,16 +65,17 @@ import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.CachingValueExpressionEvaluatorFactory;
|
||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.EntityInstantiator;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.ValueExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -92,7 +96,7 @@ import com.couchbase.client.java.json.JsonObject;
|
||||
* @author Remi Bleuse
|
||||
* @author Vipul Gupta
|
||||
*/
|
||||
public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware {
|
||||
public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware, EnvironmentCapable, EnvironmentAware {
|
||||
|
||||
/**
|
||||
* The default "type key", the name of the field that will hold type information.
|
||||
@@ -113,6 +117,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
* Spring Expression Language context.
|
||||
*/
|
||||
private final SpELContext spELContext;
|
||||
|
||||
private final SpelExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory;
|
||||
/**
|
||||
* The overall application context.
|
||||
*/
|
||||
@@ -127,6 +135,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
*/
|
||||
private @Nullable EntityCallbacks entityCallbacks;
|
||||
|
||||
private @Nullable Environment environment;
|
||||
|
||||
public MappingCouchbaseConverter() {
|
||||
this(new CouchbaseMappingContext(), null);
|
||||
}
|
||||
@@ -173,6 +183,9 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
((CouchbaseMappingContext) mappingContext).setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
|
||||
typeMapper = new DefaultCouchbaseTypeMapper(typeKey != null ? typeKey : TYPEKEY_DEFAULT);
|
||||
spELContext = new SpELContext(CouchbaseDocumentPropertyAccessor.INSTANCE);
|
||||
|
||||
expressionEvaluatorFactory = new CachingValueExpressionEvaluatorFactory(
|
||||
expressionParser, this, o -> spELContext.getEvaluationContext(o));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,6 +213,21 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
return left.isAssignableFrom(right) && !left.equals(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment getEnvironment() {
|
||||
|
||||
if (this.environment == null) {
|
||||
this.environment = new StandardEnvironment();
|
||||
}
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> getMappingContext() {
|
||||
return mappingContext;
|
||||
@@ -273,7 +301,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
* @return the converted entity.
|
||||
*/
|
||||
protected <R> R read(final CouchbasePersistentEntity<R> entity, final CouchbaseDocument source, final Object parent) {
|
||||
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(source, spELContext);
|
||||
|
||||
ValueExpressionEvaluator evaluator = expressionEvaluatorFactory.create(source);
|
||||
ParameterValueProvider<CouchbasePersistentProperty> provider = getParameterProvider(entity, source, evaluator,
|
||||
parent);
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
@@ -284,7 +313,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
entity.doWithProperties(new PropertyHandler<>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(final CouchbasePersistentProperty prop) {
|
||||
if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop) || isIdConstructionProperty(prop)
|
||||
if (!doesPropertyExistInSource(prop) || entity.isCreatorArgument(prop) || isIdConstructionProperty(prop)
|
||||
|| prop.isAnnotationPresent(N1qlJoin.class)) {
|
||||
return;
|
||||
}
|
||||
@@ -330,7 +359,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
*/
|
||||
protected Object getValueInternal(final CouchbasePersistentProperty property, final CouchbaseDocument source,
|
||||
final Object parent, PersistentEntity entity) {
|
||||
return new CouchbasePropertyValueProvider(source, spELContext, parent, entity).getPropertyValue(property);
|
||||
return new CouchbasePropertyValueProvider(source, expressionEvaluatorFactory.create(source), parent, entity).getPropertyValue(property);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,7 +373,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
*/
|
||||
private ParameterValueProvider<CouchbasePersistentProperty> getParameterProvider(
|
||||
final CouchbasePersistentEntity<?> entity, final CouchbaseDocument source,
|
||||
final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
|
||||
final ValueExpressionEvaluator evaluator, final Object parent) {
|
||||
CouchbasePropertyValueProvider provider = new CouchbasePropertyValueProvider(source, evaluator, parent, entity);
|
||||
PersistentEntityParameterValueProvider<CouchbasePersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<>(
|
||||
entity, provider, parent);
|
||||
@@ -1070,7 +1099,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
/**
|
||||
* The expression evaluator.
|
||||
*/
|
||||
private final SpELExpressionEvaluator evaluator;
|
||||
private final ValueExpressionEvaluator evaluator;
|
||||
|
||||
/**
|
||||
* The optional parent object.
|
||||
@@ -1082,15 +1111,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
*/
|
||||
private final PersistentEntity entity;
|
||||
|
||||
public CouchbasePropertyValueProvider(final CouchbaseDocument source, final SpELContext factory,
|
||||
final Object parent, final PersistentEntity entity) {
|
||||
this(source, new DefaultSpELExpressionEvaluator(source, factory), parent, entity);
|
||||
}
|
||||
|
||||
public CouchbasePropertyValueProvider(final CouchbaseDocument source,
|
||||
final DefaultSpELExpressionEvaluator evaluator, final Object parent, final PersistentEntity entity) {
|
||||
final ValueExpressionEvaluator evaluator, final Object parent, final PersistentEntity entity) {
|
||||
Assert.notNull(source, "CouchbaseDocument must not be null!");
|
||||
Assert.notNull(evaluator, "DefaultSpELExpressionEvaluator must not be null!");
|
||||
Assert.notNull(evaluator, "ValueExpressionEvaluator must not be null!");
|
||||
|
||||
this.source = source;
|
||||
this.evaluator = evaluator;
|
||||
@@ -1148,11 +1172,11 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
* A expression parameter value provider.
|
||||
*/
|
||||
private class ConverterAwareSpELExpressionParameterValueProvider
|
||||
extends SpELExpressionParameterValueProvider<CouchbasePersistentProperty> {
|
||||
extends ValueExpressionParameterValueProvider<CouchbasePersistentProperty> {
|
||||
|
||||
private final Object parent;
|
||||
|
||||
public ConverterAwareSpELExpressionParameterValueProvider(final SpELExpressionEvaluator evaluator,
|
||||
public ConverterAwareSpELExpressionParameterValueProvider(final ValueExpressionEvaluator evaluator,
|
||||
final ConversionService conversionService, final ParameterValueProvider<CouchbasePersistentProperty> delegate,
|
||||
final Object parent) {
|
||||
super(evaluator, conversionService, delegate);
|
||||
@@ -1160,8 +1184,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> T potentiallyConvertSpelValue(final Object object,
|
||||
final Parameter<T, CouchbasePersistentProperty> parameter) {
|
||||
protected <T> T potentiallyConvertExpressionValue(Object object, Parameter<T, CouchbasePersistentProperty> parameter) {
|
||||
return readValue(object, parameter.getType(), parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,8 @@ import org.springframework.data.couchbase.repository.query.StringBasedN1qlQueryP
|
||||
import org.springframework.data.couchbase.repository.support.MappingCouchbaseEntityInformation;
|
||||
import org.springframework.data.mapping.Alias;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
@@ -35,37 +34,34 @@ import com.couchbase.client.java.json.JsonValue;
|
||||
|
||||
/**
|
||||
* Query created from the string in @Query annotation in the repository interface.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and firstname = $1 and lastname = $2")
|
||||
* List<User> getByFirstnameAndLastname(String firstname, String lastname);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* It must include the SELECT ... FROM ... preferably via the #n1ql expression, in addition to any predicates required,
|
||||
* including the n1ql.filter (for _class = className)
|
||||
*
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
public class StringQuery extends Query {
|
||||
|
||||
private final CouchbaseQueryMethod queryMethod;
|
||||
private final String inlineN1qlQuery;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
private final ParameterAccessor parameterAccessor;
|
||||
private final SpelExpressionParser spelExpressionParser;
|
||||
|
||||
public StringQuery(CouchbaseQueryMethod queryMethod, String n1qlString,
|
||||
QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider, ParameterAccessor parameterAccessor,
|
||||
SpelExpressionParser spelExpressionParser) {
|
||||
ValueExpressionDelegate valueExpressionDelegate, ParameterAccessor parameterAccessor) {
|
||||
this.queryMethod = queryMethod;
|
||||
this.inlineN1qlQuery = n1qlString;
|
||||
this.evaluationContextProvider = queryMethodEvaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
this.parameterAccessor = parameterAccessor;
|
||||
this.spelExpressionParser = spelExpressionParser;
|
||||
}
|
||||
|
||||
public StringQuery(String n1qlString) {
|
||||
this(null,n1qlString, null, null, null);
|
||||
this(null,n1qlString, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,8 +71,7 @@ public class StringQuery extends Query {
|
||||
StringBasedN1qlQueryParser parser = getStringN1qlQueryParser(converter, bucketName, scope, collection, domainClass,
|
||||
distinctFields, fields);
|
||||
|
||||
N1QLExpression parsedExpression = parser.getExpression(inlineN1qlQuery, queryMethod, parameterAccessor,
|
||||
spelExpressionParser, evaluationContextProvider);
|
||||
N1QLExpression parsedExpression = parser.getExpression(inlineN1qlQuery, queryMethod, parameterAccessor, valueExpressionDelegate);
|
||||
|
||||
String queryString = parsedExpression.toString();
|
||||
|
||||
@@ -128,8 +123,7 @@ public class StringQuery extends Query {
|
||||
}
|
||||
// there are no options for distinct and fields for @Query
|
||||
StringBasedN1qlQueryParser sbnqp = new StringBasedN1qlQueryParser(inlineN1qlQuery, queryMethod, bucketName,
|
||||
scopeName, collectionName, converter, typeKey, typeValue, parameterAccessor, new SpelExpressionParser(),
|
||||
evaluationContextProvider);
|
||||
scopeName, collectionName, converter, typeKey, typeValue, parameterAccessor, valueExpressionDelegate);
|
||||
|
||||
return sbnqp;
|
||||
}
|
||||
@@ -144,7 +138,7 @@ public class StringQuery extends Query {
|
||||
|
||||
/**
|
||||
* toN1qlRemoveString - use toN1qlSelectString
|
||||
*
|
||||
*
|
||||
* @param converter
|
||||
* @param bucketName
|
||||
* @param scopeName
|
||||
|
||||
@@ -27,10 +27,9 @@ import org.springframework.data.couchbase.repository.query.CouchbaseQueryExecuti
|
||||
import org.springframework.data.repository.core.EntityMetadata;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -52,16 +51,14 @@ public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase<
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
*/
|
||||
public AbstractCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
super(method, operations, expressionParser, evaluationContextProvider);
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
super(method, operations, valueExpressionDelegate);
|
||||
Assert.notNull(method, "CouchbaseQueryMethod must not be null!");
|
||||
Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!");
|
||||
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
|
||||
Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!");
|
||||
Assert.notNull(valueExpressionDelegate, "QueryMethodEvaluationContextProvider must not be null!");
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
Class<?> type = metadata.getJavaType();
|
||||
this.findOp = (ExecutableFindByQuery<?>) (operations.findByQuery(type).inScope(method.getScope())
|
||||
|
||||
@@ -26,11 +26,10 @@ import org.springframework.data.mapping.model.EntityInstantiators;
|
||||
import org.springframework.data.repository.core.EntityMetadata;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -47,8 +46,7 @@ public abstract class AbstractCouchbaseQueryBase<CouchbaseOperationsType> implem
|
||||
private final CouchbaseOperationsType operations;
|
||||
private final EntityInstantiators instantiators;
|
||||
private final ExecutableFindByQuery<?> findOperationWithProjection;
|
||||
private final SpelExpressionParser expressionParser;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractCouchbaseQuery} from the given {@link ReactiveCouchbaseQueryMethod} and
|
||||
@@ -56,22 +54,19 @@ public abstract class AbstractCouchbaseQueryBase<CouchbaseOperationsType> implem
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
*/
|
||||
public AbstractCouchbaseQueryBase(CouchbaseQueryMethod method, CouchbaseOperationsType operations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
|
||||
Assert.notNull(method, "CouchbaseQueryMethod must not be null!");
|
||||
Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!");
|
||||
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
|
||||
Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!");
|
||||
Assert.notNull(valueExpressionDelegate, "ValueExpressionDelegate must not be null!");
|
||||
|
||||
this.method = method;
|
||||
this.operations = operations;
|
||||
this.instantiators = new EntityInstantiators();
|
||||
this.expressionParser = expressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
Class<?> type = metadata.getJavaType();
|
||||
|
||||
@@ -26,10 +26,9 @@ import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseQuer
|
||||
import org.springframework.data.repository.core.EntityMetadata;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -51,16 +50,13 @@ public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQu
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
*/
|
||||
public AbstractReactiveCouchbaseQuery(ReactiveCouchbaseQueryMethod method, ReactiveCouchbaseOperations operations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
super(method, operations, expressionParser, evaluationContextProvider);
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
super(method, operations, valueExpressionDelegate);
|
||||
Assert.notNull(method, "CouchbaseQueryMethod must not be null!");
|
||||
Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!");
|
||||
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
|
||||
Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!");
|
||||
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
Class<?> type = metadata.getJavaType();
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.springframework.data.couchbase.repository.query;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
@@ -32,19 +32,19 @@ public class CouchbaseRepositoryQuery implements RepositoryQuery {
|
||||
private final CouchbaseOperations operations;
|
||||
private final CouchbaseQueryMethod queryMethod;
|
||||
private final NamedQueries namedQueries;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public CouchbaseRepositoryQuery(final CouchbaseOperations operations, final CouchbaseQueryMethod queryMethod,
|
||||
final NamedQueries namedQueries) {
|
||||
this.operations = operations;
|
||||
this.queryMethod = queryMethod;
|
||||
this.namedQueries = namedQueries;
|
||||
this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT;
|
||||
this.valueExpressionDelegate = ValueExpressionDelegate.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(final Object[] parameters) {
|
||||
return new N1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, evaluationContextProvider)
|
||||
return new N1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, valueExpressionDelegate)
|
||||
.execute(parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
@@ -39,14 +39,14 @@ public class N1qlRepositoryQueryExecutor {
|
||||
private final CouchbaseOperations operations;
|
||||
private final CouchbaseQueryMethod queryMethod;
|
||||
private final NamedQueries namedQueries;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public N1qlRepositoryQueryExecutor(final CouchbaseOperations operations, final CouchbaseQueryMethod queryMethod,
|
||||
final NamedQueries namedQueries, final QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
final NamedQueries namedQueries, final ValueExpressionDelegate valueExpressionDelegate) {
|
||||
this.operations = operations;
|
||||
this.queryMethod = queryMethod;
|
||||
this.namedQueries = namedQueries;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
}
|
||||
|
||||
private static final SpelExpressionParser SPEL_PARSER = new SpelExpressionParser();
|
||||
@@ -69,8 +69,8 @@ public class N1qlRepositoryQueryExecutor {
|
||||
Query query;
|
||||
ExecutableFindByQuery q;
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
query = new StringN1qlQueryCreator(accessor, queryMethod, operations.getConverter(), SPEL_PARSER,
|
||||
evaluationContextProvider, namedQueries).createQuery();
|
||||
query = new StringN1qlQueryCreator(accessor, queryMethod, operations.getConverter(),
|
||||
valueExpressionDelegate, namedQueries).createQuery();
|
||||
} else {
|
||||
final PartTree tree = new PartTree(queryMethod.getName(), domainClass);
|
||||
query = new N1qlQueryCreator(tree, accessor, queryMethod, operations.getConverter(), operations.getBucketName())
|
||||
|
||||
@@ -21,11 +21,10 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* {@link RepositoryQuery} implementation for Couchbase. Replaces PartTreeN1qlBasedQuery
|
||||
@@ -43,13 +42,11 @@ public class PartTreeCouchbaseQuery extends AbstractCouchbaseQuery {
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
*/
|
||||
public PartTreeCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
public PartTreeCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations, ValueExpressionDelegate valueExpressionDelegate) {
|
||||
|
||||
super(method, operations, expressionParser, evaluationContextProvider);
|
||||
super(method, operations, valueExpressionDelegate);
|
||||
|
||||
ResultProcessor processor = method.getResultProcessor();
|
||||
this.tree = new CouchbasePartTree(method.getName(), processor.getReturnedType().getDomainType());
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.springframework.data.repository.util.ClassUtils.hasParameterOfType;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@@ -29,8 +27,9 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.util.ReactiveWrappers;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.ReactiveWrappers;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -60,7 +59,7 @@ public class ReactiveCouchbaseQueryMethod extends CouchbaseQueryMethod {
|
||||
|
||||
super(method, metadata, projectionFactory, mappingContext);
|
||||
|
||||
if (hasParameterOfType(method, Pageable.class)) {
|
||||
if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) {
|
||||
|
||||
TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
|
||||
|
||||
@@ -81,7 +80,7 @@ public class ReactiveCouchbaseQueryMethod extends CouchbaseQueryMethod {
|
||||
method.toString()));
|
||||
}
|
||||
|
||||
if (hasParameterOfType(method, Sort.class)) {
|
||||
if (ReflectionUtils.hasParameterOfType(method, Sort.class)) {
|
||||
throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameter. "
|
||||
+ "Use sorting capabilities on Pageable instead! Offending method: %s", method.toString()));
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
@@ -33,20 +32,20 @@ public class ReactiveCouchbaseRepositoryQuery extends AbstractReactiveCouchbaseQ
|
||||
private final ReactiveCouchbaseOperations operations;
|
||||
private final ReactiveCouchbaseQueryMethod queryMethod;
|
||||
private final NamedQueries namedQueries;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public ReactiveCouchbaseRepositoryQuery(final ReactiveCouchbaseOperations operations,
|
||||
final ReactiveCouchbaseQueryMethod queryMethod, final NamedQueries namedQueries) {
|
||||
super(queryMethod, operations, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT);
|
||||
super(queryMethod, operations, ValueExpressionDelegate.create());
|
||||
this.operations = operations;
|
||||
this.queryMethod = queryMethod;
|
||||
this.namedQueries = namedQueries;
|
||||
this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT;
|
||||
this.valueExpressionDelegate = ValueExpressionDelegate.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(final Object[] parameters) {
|
||||
return new ReactiveN1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, evaluationContextProvider)
|
||||
return new ReactiveN1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, valueExpressionDelegate)
|
||||
.execute(parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@ package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
@@ -31,15 +30,15 @@ public class ReactiveN1qlRepositoryQueryExecutor {
|
||||
private final ReactiveCouchbaseOperations operations;
|
||||
private final ReactiveCouchbaseQueryMethod queryMethod;
|
||||
private final NamedQueries namedQueries;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations operations,
|
||||
final ReactiveCouchbaseQueryMethod queryMethod, final NamedQueries namedQueries,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
this.operations = operations;
|
||||
this.queryMethod = queryMethod;
|
||||
this.namedQueries = namedQueries;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,11 +51,9 @@ public class ReactiveN1qlRepositoryQueryExecutor {
|
||||
// counterpart to N1qlRespositoryQueryExecutor,
|
||||
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
return new ReactiveStringBasedCouchbaseQuery(queryMethod, operations, new SpelExpressionParser(),
|
||||
evaluationContextProvider, namedQueries).execute(parameters);
|
||||
return new ReactiveStringBasedCouchbaseQuery(queryMethod, operations, valueExpressionDelegate, namedQueries).execute(parameters);
|
||||
} else {
|
||||
return new ReactivePartTreeCouchbaseQuery(queryMethod, operations, new SpelExpressionParser(),
|
||||
evaluationContextProvider).execute(parameters);
|
||||
return new ReactivePartTreeCouchbaseQuery(queryMethod, operations, valueExpressionDelegate).execute(parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,10 +23,9 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* Reactive PartTree {@link RepositoryQuery} implementation for Couchbase. Replaces ReactivePartN1qlBasedQuery
|
||||
@@ -46,13 +45,12 @@ public class ReactivePartTreeCouchbaseQuery extends AbstractReactiveCouchbaseQue
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
*/
|
||||
public ReactivePartTreeCouchbaseQuery(ReactiveCouchbaseQueryMethod method, ReactiveCouchbaseOperations operations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
|
||||
super(method, operations, expressionParser, evaluationContextProvider);
|
||||
super(method, operations, valueExpressionDelegate);
|
||||
this.tree = new PartTree(method.getName(), method.getResultProcessor().getReturnedType().getDomainType());
|
||||
this.converter = operations.getConverter();
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
||||
@@ -36,30 +34,24 @@ public class ReactiveStringBasedCouchbaseQuery extends AbstractReactiveCouchbase
|
||||
private static final String COUNT_EXISTS_AND_DELETE = "Manually defined query for %s cannot be a count and exists or delete query at the same time!";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ReactiveStringBasedCouchbaseQuery.class);
|
||||
|
||||
private final SpelExpressionParser expressionParser;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
private final NamedQueries namedQueries;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ReactiveStringBasedCouchbaseQuery} for the given {@link String}, {@link CouchbaseQueryMethod},
|
||||
* {@link ReactiveCouchbaseOperations}, {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}.
|
||||
* {@link ReactiveCouchbaseOperations}, and {@link ValueExpressionDelegate}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param couchbaseOperations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
* @param namedQueries must not be {@literal null}.
|
||||
*/
|
||||
public ReactiveStringBasedCouchbaseQuery(ReactiveCouchbaseQueryMethod method,
|
||||
ReactiveCouchbaseOperations couchbaseOperations, SpelExpressionParser expressionParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider, NamedQueries namedQueries) {
|
||||
ReactiveCouchbaseOperations couchbaseOperations, ValueExpressionDelegate valueExpressionDelegate, NamedQueries namedQueries) {
|
||||
|
||||
super(method, couchbaseOperations, expressionParser, evaluationContextProvider);
|
||||
super(method, couchbaseOperations, valueExpressionDelegate);
|
||||
|
||||
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
|
||||
|
||||
this.expressionParser = expressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
|
||||
if (hasAmbiguousProjectionFlags(isCountQuery(), isExistsQuery(), isDeleteQuery())) {
|
||||
throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method));
|
||||
@@ -77,7 +69,7 @@ public class ReactiveStringBasedCouchbaseQuery extends AbstractReactiveCouchbase
|
||||
protected Query createQuery(ParametersParameterAccessor accessor) {
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(accessor, getQueryMethod(),
|
||||
getOperations().getConverter(), expressionParser, evaluationContextProvider, namedQueries);
|
||||
getOperations().getConverter(), valueExpressionDelegate, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
|
||||
|
||||
@@ -21,9 +21,8 @@ import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
||||
@@ -36,30 +35,25 @@ public class StringBasedCouchbaseQuery extends AbstractCouchbaseQuery {
|
||||
private static final String COUNT_EXISTS_AND_DELETE = "Manually defined query for %s cannot be a count and exists or delete query at the same time!";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StringBasedCouchbaseQuery.class);
|
||||
|
||||
private final SpelExpressionParser expressionParser;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
private final NamedQueries namedQueries;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedCouchbaseQuery} for the given {@link String}, {@link CouchbaseQueryMethod},
|
||||
* {@link CouchbaseOperations}, {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}.
|
||||
* {@link CouchbaseOperations}, {@link SpelExpressionParser} and {@link ValueExpressionDelegate}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param couchbaseOperations must not be {@literal null}.
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param valueExpressionDelegate must not be {@literal null}.
|
||||
* @param namedQueries must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations couchbaseOperations,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider,
|
||||
ValueExpressionDelegate valueExpressionDelegate,
|
||||
NamedQueries namedQueries) {
|
||||
|
||||
super(method, couchbaseOperations, expressionParser, evaluationContextProvider);
|
||||
super(method, couchbaseOperations, valueExpressionDelegate);
|
||||
|
||||
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
|
||||
|
||||
this.expressionParser = expressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
|
||||
if (hasAmbiguousProjectionFlags(isCountQuery(), isExistsQuery(), isDeleteQuery())) {
|
||||
throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method));
|
||||
@@ -75,7 +69,7 @@ public class StringBasedCouchbaseQuery extends AbstractCouchbaseQuery {
|
||||
protected Query createQuery(ParametersParameterAccessor accessor) {
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(accessor, getQueryMethod(),
|
||||
getOperations().getConverter(), expressionParser, evaluationContextProvider, namedQueries);
|
||||
getOperations().getConverter(), valueExpressionDelegate, namedQueries);
|
||||
Query query = creator.createQuery();
|
||||
|
||||
if (LOG.isTraceEnabled()) {
|
||||
|
||||
@@ -15,11 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.i;
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.s;
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.x;
|
||||
import static org.springframework.data.couchbase.core.support.TemplateUtils.SELECT_CAS;
|
||||
import static org.springframework.data.couchbase.core.support.TemplateUtils.SELECT_ID;
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.*;
|
||||
import static org.springframework.data.couchbase.core.support.TemplateUtils.*;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
@@ -33,6 +30,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseList;
|
||||
@@ -42,15 +40,17 @@ import org.springframework.data.couchbase.core.query.N1QLExpression;
|
||||
import org.springframework.data.couchbase.core.query.StringQuery;
|
||||
import org.springframework.data.couchbase.repository.Query;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.expression.ValueEvaluationContext;
|
||||
import org.springframework.data.expression.ValueExpression;
|
||||
import org.springframework.data.expression.ValueExpressionParser;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.common.TemplateParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.error.CouchbaseException;
|
||||
@@ -156,21 +156,18 @@ public class StringBasedN1qlQueryParser {
|
||||
* @param typeField
|
||||
* @param typeValue
|
||||
* @param accessor
|
||||
* @param spelExpressionParser
|
||||
* @param evaluationContextProvider
|
||||
* @param valueExpressionDelegate
|
||||
*/
|
||||
public StringBasedN1qlQueryParser(String statement, CouchbaseQueryMethod queryMethod, String bucketName, String scope,
|
||||
String collection, CouchbaseConverter couchbaseConverter, String typeField, String typeValue,
|
||||
ParameterAccessor accessor, SpelExpressionParser spelExpressionParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ParameterAccessor accessor, ValueExpressionDelegate valueExpressionDelegate) {
|
||||
this.statement = statement;
|
||||
this.queryMethod = queryMethod;
|
||||
this.couchbaseConverter = couchbaseConverter;
|
||||
this.statementContext = queryMethod == null ? null
|
||||
: createN1qlSpelValues(bucketName, scope, collection,
|
||||
queryMethod.getEntityInformation().getJavaType(), typeField, typeValue, queryMethod.isCountQuery(), null, null);
|
||||
this.parsedExpression = getExpression(statement, queryMethod, accessor, spelExpressionParser,
|
||||
evaluationContextProvider);
|
||||
: createN1qlSpelValues(bucketName, scope, collection, queryMethod.getEntityInformation().getJavaType(),
|
||||
typeField, typeValue, queryMethod.isCountQuery(), null, null);
|
||||
this.parsedExpression = getExpression(statement, queryMethod, accessor, valueExpressionDelegate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,22 +198,22 @@ public class StringBasedN1qlQueryParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the n1ql spel values. The domainClass is needed, but not the returnClass. Mapping the domainClass to the
|
||||
* returnClass is the responsibility of decoding.
|
||||
*
|
||||
* @param bucketName
|
||||
* @param scope
|
||||
* @param collection
|
||||
* @param domainClass
|
||||
* @param typeKey
|
||||
* @param typeValue
|
||||
* @param isCount
|
||||
* @param distinctFields
|
||||
* @param fields
|
||||
* @return
|
||||
*/
|
||||
* Create the n1ql spel values. The domainClass is needed, but not the returnClass. Mapping the domainClass to the
|
||||
* returnClass is the responsibility of decoding.
|
||||
*
|
||||
* @param bucketName
|
||||
* @param scope
|
||||
* @param collection
|
||||
* @param domainClass
|
||||
* @param typeKey
|
||||
* @param typeValue
|
||||
* @param isCount
|
||||
* @param distinctFields
|
||||
* @param fields
|
||||
* @return
|
||||
*/
|
||||
public N1qlSpelValues createN1qlSpelValues(String bucketName, String scope, String collection, Class domainClass,
|
||||
String typeKey, String typeValue, boolean isCount, String[] distinctFields, String[] fields) {
|
||||
String typeKey, String typeValue, boolean isCount, String[] distinctFields, String[] fields) {
|
||||
String b = bucketName;
|
||||
String keyspace = collection != null ? collection : bucketName;
|
||||
Assert.isTrue(!(distinctFields != null && fields != null),
|
||||
@@ -224,7 +221,7 @@ public class StringBasedN1qlQueryParser {
|
||||
String entityFields = "";
|
||||
String selectEntity;
|
||||
if (distinctFields != null) {
|
||||
String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, typeKey, fields, distinctFields);
|
||||
String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, typeKey, fields, distinctFields);
|
||||
if (isCount) {
|
||||
selectEntity = N1QLExpression.select(N1QLExpression.count(N1QLExpression.distinct(x(distinctFieldsStr)))
|
||||
.as(i(CountFragment.COUNT_ALIAS)).from(keyspace)).toString();
|
||||
@@ -235,12 +232,11 @@ public class StringBasedN1qlQueryParser {
|
||||
selectEntity = N1QLExpression.select(N1QLExpression.count(x("\"*\"")).as(i(CountFragment.COUNT_ALIAS)))
|
||||
.from(keyspace).toString();
|
||||
} else {
|
||||
String projectedFields = getProjectedOrDistinctFields(keyspace, domainClass, typeKey, fields,
|
||||
distinctFields);
|
||||
String projectedFields = getProjectedOrDistinctFields(keyspace, domainClass, typeKey, fields, distinctFields);
|
||||
entityFields = projectedFields;
|
||||
selectEntity = N1QLExpression.select(x(projectedFields)).from(keyspace).toString();
|
||||
}
|
||||
String typeSelection = !empty(typeKey) && !empty(typeValue) ? i(typeKey).eq(s(typeValue)).toString() : null;
|
||||
String typeSelection = !empty(typeKey) && !empty(typeValue) ? i(typeKey).eq(s(typeValue)).toString() : null;
|
||||
|
||||
String delete = N1QLExpression.delete().from(keyspace).toString();
|
||||
String returning = " returning " + N1qlUtils.createReturningExpressionForDelete(keyspace);
|
||||
@@ -249,9 +245,9 @@ public class StringBasedN1qlQueryParser {
|
||||
i(collection).toString(), typeSelection, delete, returning);
|
||||
}
|
||||
|
||||
private static boolean empty(String s) {
|
||||
return s == null || s.length() == 0;
|
||||
}
|
||||
private static boolean empty(String s) {
|
||||
return s == null || s.length() == 0;
|
||||
}
|
||||
|
||||
private String getProjectedOrDistinctFields(String b, Class resultClass, String typeField, String[] fields,
|
||||
String[] distinctFields) {
|
||||
@@ -373,12 +369,16 @@ public class StringBasedN1qlQueryParser {
|
||||
|
||||
// this static method can be used to test the parsing behavior for Couchbase specific spel variables
|
||||
// in isolation from the rest of the spel parser initialization chain.
|
||||
public static String doParse(String statement, SpelExpressionParser parser, EvaluationContext evaluationContext,
|
||||
N1qlSpelValues n1qlSpelValues) {
|
||||
org.springframework.expression.Expression parsedExpression = parser.parseExpression(statement,
|
||||
new TemplateParserContext());
|
||||
evaluationContext.setVariable(SPEL_PREFIX, n1qlSpelValues);
|
||||
return parsedExpression.getValue(evaluationContext, String.class);
|
||||
public static String doParse(String statement, ValueExpressionParser parser,
|
||||
ValueEvaluationContext valueEvaluationContext, N1qlSpelValues n1qlSpelValues) {
|
||||
ValueExpression parsedExpression = parser.parse(statement);
|
||||
|
||||
EvaluationContext evaluationContext = valueEvaluationContext.getRequiredEvaluationContext();
|
||||
if (evaluationContext instanceof StandardEvaluationContext ctx) {
|
||||
ctx.setVariable(SPEL_PREFIX, n1qlSpelValues);
|
||||
}
|
||||
Object result = parsedExpression.evaluate(valueEvaluationContext);
|
||||
return result != null ? result.toString() : null;
|
||||
}
|
||||
|
||||
private void checkPlaceholders(String statement) {
|
||||
@@ -386,9 +386,8 @@ public class StringBasedN1qlQueryParser {
|
||||
Matcher quoteMatcher = QUOTE_DETECTION_PATTERN.matcher(statement);
|
||||
Matcher positionMatcher = POSITIONAL_PLACEHOLDER_PATTERN.matcher(statement);
|
||||
Matcher namedMatcher = NAMED_PLACEHOLDER_PATTERN.matcher(statement);
|
||||
String queryIdentifier = (this.queryMethod != null ? queryMethod.getClass().getName()
|
||||
: StringQuery.class.getName()) + "."
|
||||
+ (this.queryMethod != null ? queryMethod.getName() : this.statement);
|
||||
String queryIdentifier = (this.queryMethod != null ? queryMethod.getClass().getName() : StringQuery.class.getName())
|
||||
+ "." + (this.queryMethod != null ? queryMethod.getName() : this.statement);
|
||||
|
||||
List<int[]> quotes = new ArrayList<int[]>();
|
||||
while (quoteMatcher.find()) {
|
||||
@@ -404,8 +403,7 @@ public class StringBasedN1qlQueryParser {
|
||||
if (checkNotQuoted(placeholder, positionMatcher.start(), positionMatcher.end(), quotes, queryIdentifier)) {
|
||||
if (this.queryMethod == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"StringQuery created from StringQuery(String) cannot have parameters. "
|
||||
+ "They cannot be processed. "
|
||||
"StringQuery created from StringQuery(String) cannot have parameters. " + "They cannot be processed. "
|
||||
+ "Use an @Query annotated method and the SPEL Expression #{[<n>]} : " + statement);
|
||||
}
|
||||
LOGGER.trace("{}: Found positional placeholder {}", queryIdentifier, placeholder);
|
||||
@@ -419,9 +417,8 @@ public class StringBasedN1qlQueryParser {
|
||||
// check not in quoted
|
||||
if (checkNotQuoted(placeholder, namedMatcher.start(), namedMatcher.end(), quotes, queryIdentifier)) {
|
||||
if (this.queryMethod == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"StringQuery created from StringQuery(String) cannot have parameters. "
|
||||
+ "Use an @Query annotated method and the SPEL Expression #{[<n>]} : " + statement);
|
||||
throw new IllegalArgumentException("StringQuery created from StringQuery(String) cannot have parameters. "
|
||||
+ "Use an @Query annotated method and the SPEL Expression #{[<n>]} : " + statement);
|
||||
}
|
||||
LOGGER.trace("{}: Found named placeholder {}", queryIdentifier, placeholder);
|
||||
namedCount++;
|
||||
@@ -449,10 +446,8 @@ public class StringBasedN1qlQueryParser {
|
||||
// check not in quoted
|
||||
if (checkNotQuoted(placeholder, spelMatcher.start(), spelMatcher.end(), quotes, queryIdentifier)) {
|
||||
if (this.queryMethod == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"StringQuery created from StringQuery(String) cannot SPEL expressions. "
|
||||
+ "Use an @Query annotated method and the SPEL Expression #{[<n>]} : "
|
||||
+ statement);
|
||||
throw new IllegalArgumentException("StringQuery created from StringQuery(String) cannot SPEL expressions. "
|
||||
+ "Use an @Query annotated method and the SPEL Expression #{[<n>]} : " + statement);
|
||||
}
|
||||
LOGGER.trace("{}: Found SPEL Experssion {}", queryIdentifier, placeholder);
|
||||
}
|
||||
@@ -686,19 +681,18 @@ public class StringBasedN1qlQueryParser {
|
||||
* @param statement
|
||||
* @param queryMethod
|
||||
* @param accessor
|
||||
* @param parser
|
||||
* @param evaluationContextProvider
|
||||
* @param valueExpressionDelegate
|
||||
* @return
|
||||
*/
|
||||
|
||||
public N1QLExpression getExpression(String statement, CouchbaseQueryMethod queryMethod, ParameterAccessor accessor,
|
||||
SpelExpressionParser parser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
N1QLExpression parsedStatement;
|
||||
if (accessor != null && queryMethod != null && parser != null) {
|
||||
if (accessor != null && queryMethod != null) {
|
||||
Object[] runtimeParameters = getParameters(accessor);
|
||||
EvaluationContext evaluationContext = evaluationContextProvider
|
||||
.getEvaluationContext(queryMethod.getParameters(), runtimeParameters);
|
||||
parsedStatement = x(doParse(statement, parser, evaluationContext, this.getStatementContext()));
|
||||
ValueEvaluationContext evaluationContext = valueExpressionDelegate
|
||||
.createValueContextProvider(queryMethod.getParameters()).getEvaluationContext(runtimeParameters);
|
||||
parsedStatement = x(doParse(statement, valueExpressionDelegate, evaluationContext, this.getStatementContext()));
|
||||
} else {
|
||||
parsedStatement = x(statement);
|
||||
}
|
||||
@@ -711,7 +705,7 @@ public class StringBasedN1qlQueryParser {
|
||||
for (Object o : accessor) {
|
||||
params.add(o);
|
||||
}
|
||||
if( accessor.getPageable().isPaged()) {
|
||||
if (accessor.getPageable().isPaged()) {
|
||||
params.add(accessor.getPageable());
|
||||
} else if (accessor.getSort().isSorted()) {
|
||||
params.add(accessor.getSort());
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.x;
|
||||
import static org.springframework.data.couchbase.core.query.QueryCriteria.where;
|
||||
import static org.springframework.data.couchbase.core.query.N1QLExpression.*;
|
||||
import static org.springframework.data.couchbase.core.query.QueryCriteria.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
@@ -33,11 +33,10 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
@@ -48,15 +47,14 @@ public class StringN1qlQueryCreator extends AbstractQueryCreator<Query, QueryCri
|
||||
// everything we need in the StringQuery such that we can doParse() later when we have the scope and collection
|
||||
private final ParameterAccessor accessor;
|
||||
private final MappingContext<?, CouchbasePersistentProperty> context;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
private final CouchbaseQueryMethod queryMethod;
|
||||
private final CouchbaseConverter couchbaseConverter;
|
||||
private final String queryString;
|
||||
private final SpelExpressionParser spelExpressionParser;
|
||||
|
||||
public StringN1qlQueryCreator(final ParameterAccessor accessor, CouchbaseQueryMethod queryMethod,
|
||||
CouchbaseConverter couchbaseConverter, SpelExpressionParser spelExpressionParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider, NamedQueries namedQueries) {
|
||||
CouchbaseConverter couchbaseConverter,
|
||||
ValueExpressionDelegate valueExpressionDelegate, NamedQueries namedQueries) {
|
||||
|
||||
// AbstractQueryCreator needs a PartTree, so we give it a dummy one.
|
||||
// The resulting dummy criteria will not be included in the Query
|
||||
@@ -68,8 +66,7 @@ public class StringN1qlQueryCreator extends AbstractQueryCreator<Query, QueryCri
|
||||
this.context = couchbaseConverter.getMappingContext();
|
||||
this.queryMethod = queryMethod;
|
||||
this.couchbaseConverter = couchbaseConverter;
|
||||
this.spelExpressionParser = spelExpressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
final String namedQueryName = queryMethod.getNamedQueryName();
|
||||
String qString;
|
||||
if (queryMethod.hasInlineN1qlQuery()) {
|
||||
@@ -133,7 +130,7 @@ public class StringN1qlQueryCreator extends AbstractQueryCreator<Query, QueryCri
|
||||
@Override
|
||||
protected Query complete(QueryCriteria criteria, Sort sort) {
|
||||
// everything we need in the StringQuery such that we can doParse() later when we have the scope and collection
|
||||
Query q = new StringQuery(queryMethod, queryString, evaluationContextProvider, accessor, spelExpressionParser)
|
||||
Query q = new StringQuery(queryMethod, queryString, valueExpressionDelegate, accessor)
|
||||
.with(sort);
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.support;
|
||||
|
||||
import static org.springframework.data.querydsl.QuerydslUtils.QUERY_DSL_PRESENT;
|
||||
import static org.springframework.data.querydsl.QuerydslUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -39,9 +39,10 @@ import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryComposition;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.CachingValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -142,8 +143,8 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
@Override
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key,
|
||||
QueryMethodEvaluationContextProvider contextProvider) {
|
||||
return Optional.of(new CouchbaseQueryLookupStrategy(contextProvider));
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
return Optional.of(new CouchbaseQueryLookupStrategy(valueExpressionDelegate));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,10 +152,10 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
*/
|
||||
private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public CouchbaseQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
public CouchbaseQueryLookupStrategy(ValueExpressionDelegate valueExpressionDelegate) {
|
||||
this.valueExpressionDelegate = new CachingValueExpressionDelegate(valueExpressionDelegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,11 +167,11 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext);
|
||||
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
return new StringBasedCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(),
|
||||
evaluationContextProvider, namedQueries);
|
||||
return new StringBasedCouchbaseQuery(queryMethod, couchbaseOperations,
|
||||
valueExpressionDelegate, namedQueries);
|
||||
} else {
|
||||
return new PartTreeCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(),
|
||||
evaluationContextProvider);
|
||||
return new PartTreeCouchbaseQuery(queryMethod, couchbaseOperations,
|
||||
valueExpressionDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.ReactiveRepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -132,8 +132,8 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
|
||||
@Override
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key,
|
||||
QueryMethodEvaluationContextProvider contextProvider) {
|
||||
return Optional.of(new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(contextProvider));
|
||||
ValueExpressionDelegate valueExpressionDelegate) {
|
||||
return Optional.of(new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(valueExpressionDelegate));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,10 +141,10 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
*/
|
||||
private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ValueExpressionDelegate valueExpressionDelegate;
|
||||
|
||||
public CouchbaseQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
public CouchbaseQueryLookupStrategy(ValueExpressionDelegate valueExpressionDelegate) {
|
||||
this.valueExpressionDelegate = valueExpressionDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,11 +156,11 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
mappingContext);
|
||||
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
return new ReactiveStringBasedCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(),
|
||||
evaluationContextProvider, namedQueries);
|
||||
return new ReactiveStringBasedCouchbaseQuery(queryMethod, couchbaseOperations,
|
||||
valueExpressionDelegate, namedQueries);
|
||||
} else {
|
||||
return new ReactivePartTreeCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(),
|
||||
evaluationContextProvider);
|
||||
return new ReactivePartTreeCouchbaseQuery(queryMethod, couchbaseOperations,
|
||||
valueExpressionDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.index.CompositeQueryIndex;
|
||||
import org.springframework.data.couchbase.core.index.QueryIndexed;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@@ -34,7 +34,7 @@ public class Airline extends ComparableEntity {
|
||||
|
||||
String hqCountry;
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public Airline(String id, String name, String hqCountry) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.couchbase.core.index.CompositeQueryIndex;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.index.QueryIndexed;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
import org.springframework.data.couchbase.repository.Collection;
|
||||
@@ -34,7 +33,7 @@ public class AirlineCollectioned extends ComparableEntity {
|
||||
|
||||
String hqCountry;
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public AirlineCollectioned(String id, String name, String hqCountry) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
||||
@@ -20,7 +20,7 @@ import jakarta.validation.constraints.Max;
|
||||
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@@ -59,7 +59,7 @@ public class Airport extends ComparableEntity {
|
||||
|
||||
public Airport() {}
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public Airport(String key, String iata, String icao) {
|
||||
this.key = key;
|
||||
this.iata = iata;
|
||||
|
||||
@@ -20,7 +20,7 @@ import jakarta.validation.constraints.Max;
|
||||
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@@ -61,7 +61,7 @@ public class AirportJsonValue extends ComparableEntity {
|
||||
|
||||
public AirportJsonValue() {}
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public AirportJsonValue(String key, String iata, String icao) {
|
||||
this.key = key;
|
||||
this.iata = iata;
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.data.couchbase.domain;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
/**
|
||||
@@ -34,11 +34,11 @@ public class AirportMini extends ComparableEntity {
|
||||
private String iata;
|
||||
private Address address;
|
||||
|
||||
@PersistenceConstructor
|
||||
public AirportMini(final String id, final String iata) {
|
||||
this.id = id;
|
||||
this.iata = iata;
|
||||
}
|
||||
@PersistenceCreator
|
||||
public AirportMini(final String id, final String iata) {
|
||||
this.id = id;
|
||||
this.iata = iata;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.couchbase.domain;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
@@ -29,7 +29,7 @@ public class BigAirline extends Airline {
|
||||
BigInteger airlineNumber = new BigInteger("88881234567890123456"); // less than 63 bits, otherwise query truncates
|
||||
BigDecimal airlineDecimal = new BigDecimal("888812345678901.23"); // less than 53 bits in mantissa
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public BigAirline(String id, String name, String hqCountry, Number airlineNumber, Number airlineDecimal) {
|
||||
super(id, name, hqCountry);
|
||||
this.airlineNumber = airlineNumber != null && !airlineNumber.equals("")
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@TypeAlias(AbstractingTypeMapper.Type.ABSTRACTUSER)
|
||||
public class OtherUser extends AbstractUser {
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public OtherUser(final String id, final String firstname, final String lastname) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
|
||||
@@ -17,25 +17,11 @@
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
import com.couchbase.client.java.encryption.annotation.Encrypted;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
|
||||
/**
|
||||
* UserEncrypted entity for tests
|
||||
|
||||
@@ -21,19 +21,18 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
import com.couchbase.client.java.json.JsonValue;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
@@ -53,7 +52,7 @@ public class User extends AbstractUser implements Serializable {
|
||||
public JsonObject jsonObject;
|
||||
public JsonArray jsonArray;
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public User(final String id, final String firstname, final String lastname) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
|
||||
@@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
import org.springframework.data.couchbase.repository.Collection;
|
||||
import org.springframework.data.couchbase.repository.Scope;
|
||||
@@ -33,7 +33,7 @@ import org.springframework.data.couchbase.repository.Scope;
|
||||
@Collection("other_collection")
|
||||
public class UserCol extends User {
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public UserCol(final String id, final String firstname, final String lastname) {
|
||||
super(id, firstname, lastname);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.UUID;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@@ -55,7 +55,7 @@ public class UserEncrypted extends AbstractUser implements Serializable {
|
||||
|
||||
public String _class; // cheat a little so that will work with Java SDK
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public UserEncrypted(final String id, final String firstname, final String lastname) {
|
||||
this();
|
||||
this.id = id;
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.data.couchbase.domain;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ public class UserJustLastName extends ComparableEntity {
|
||||
|
||||
public User user;
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public UserJustLastName(final String id, final String lastname) {
|
||||
this.id = id;
|
||||
this.lastname = lastname;
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.annotation.Version;
|
||||
@@ -52,7 +52,7 @@ public class UserNoAlias extends AbstractUser implements Serializable {
|
||||
public JsonObject jsonObject;
|
||||
public JsonArray jsonArray;
|
||||
|
||||
@PersistenceConstructor
|
||||
@PersistenceCreator
|
||||
public UserNoAlias(final String id, final String firstname, final String lastname) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
@@ -23,6 +23,7 @@ import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery;
|
||||
@@ -31,8 +32,8 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.domain.Airline;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
import org.springframework.data.couchbase.domain.AirlineRepository;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
import org.springframework.data.couchbase.util.Capabilities;
|
||||
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
|
||||
import org.springframework.data.couchbase.util.ClusterType;
|
||||
@@ -47,8 +48,7 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersSource;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@@ -83,7 +83,7 @@ class StringN1qlQueryCreatorIntegrationTests extends ClusterAwareIntegrationTest
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Continental"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
queryMethod, converter, ValueExpressionDelegate.create(),
|
||||
namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
@@ -116,7 +116,7 @@ class StringN1qlQueryCreatorIntegrationTests extends ClusterAwareIntegrationTest
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Continental"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
queryMethod, converter, ValueExpressionDelegate.create(),
|
||||
namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
|
||||
@@ -15,15 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
@@ -43,8 +42,7 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersSource;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
@@ -73,7 +71,7 @@ class StringN1qlQueryCreatorTests {
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
queryMethod, converter, ValueExpressionDelegate.create(),
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
@@ -91,7 +89,7 @@ class StringN1qlQueryCreatorTests {
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
queryMethod, converter, ValueExpressionDelegate.create(),
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
@@ -109,7 +107,7 @@ class StringN1qlQueryCreatorTests {
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
queryMethod, converter, ValueExpressionDelegate.create(), namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
@@ -130,7 +128,7 @@ class StringN1qlQueryCreatorTests {
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
|
||||
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
queryMethod, converter, ValueExpressionDelegate.create(), namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
@@ -203,7 +201,7 @@ class StringN1qlQueryCreatorTests {
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method)), queryMethod,
|
||||
converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
converter, ValueExpressionDelegate.create(), namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user