DATACOUCH-484 - Thread safety issue using findBy.

Support for positional parameters necessitated caching them, however
that was not done in a threadsafe fashion.  ThreadLocal storage is
sufficient to take care of the issue.  Added test for it while at it.
This commit is contained in:
David Kelly
2019-11-11 11:44:53 -07:00
parent 4a8e07f8fd
commit f69d51586d
3 changed files with 53 additions and 5 deletions

View File

@@ -50,16 +50,21 @@ import org.springframework.util.Assert;
public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
private final PartTree partTree;
private JsonValue placeHolderValues;
private ThreadLocal<JsonValue> placeHolderValues;
public PartTreeN1qlBasedQuery(CouchbaseQueryMethod queryMethod, CouchbaseOperations couchbaseOperations) {
super(queryMethod, couchbaseOperations);
this.partTree = new PartTree(queryMethod.getName(), queryMethod.getEntityInformation().getJavaType());
this.placeHolderValues = new ThreadLocal<JsonValue>() {
@Override public JsonValue initialValue() {
return JsonArray.create();
}
};
}
@Override
protected JsonValue getPlaceholderValues(ParameterAccessor accessor) {
return this.placeHolderValues;
return this.placeHolderValues.get();
}
@Override
@@ -70,7 +75,7 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
N1qlCountQueryCreator queryCountCreator = new N1qlCountQueryCreator(partTree, accessor, countFrom,
getCouchbaseOperations().getConverter(), getQueryMethod());
Statement statement = queryCountCreator.createQuery();
this.placeHolderValues = queryCountCreator.getPlaceHolderValues();
this.placeHolderValues.set(queryCountCreator.getPlaceHolderValues());
return statement;
}
@@ -83,7 +88,7 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
DeleteUsePath deleteUsePath = deleteFrom(bucket);
N1qlMutateQueryCreator mutateQueryCreator = new N1qlMutateQueryCreator(partTree, accessor, deleteUsePath, getCouchbaseOperations().getConverter(), getQueryMethod());
MutateLimitPath mutateFromWhereOrderBy = mutateQueryCreator.createQuery();
this.placeHolderValues = mutateQueryCreator.getPlaceHolderValues();
this.placeHolderValues.set(mutateQueryCreator.getPlaceHolderValues());
if (partTree.isLimiting()) {
return mutateFromWhereOrderBy.limit(partTree.getMaxResults());
@@ -101,7 +106,7 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
N1qlQueryCreator queryCreator = new N1qlQueryCreator(partTree, accessor, selectFrom,
getCouchbaseOperations().getConverter(), getQueryMethod());
LimitPath selectFromWhereOrderBy = queryCreator.createQuery();
this.placeHolderValues = queryCreator.getPlaceHolderValues();
this.placeHolderValues.set(queryCreator.getPlaceHolderValues());
if (queryMethod.isPageQuery()) {
Pageable pageable = accessor.getPageable();