Only throw exception for id and cas not projected if needed. (#1395)
Closes #1394.
This commit is contained in:
@@ -37,6 +37,7 @@ import org.springframework.data.couchbase.core.mapping.event.BeforeConvertCallba
|
||||
import org.springframework.data.couchbase.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.BeforeSaveEvent;
|
||||
import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
import org.springframework.data.couchbase.repository.support.MappingCouchbaseEntityInformation;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
@@ -45,6 +46,8 @@ import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.couchbase.client.core.error.CouchbaseException;
|
||||
|
||||
/**
|
||||
* Internal encode/decode support for CouchbaseTemplate.
|
||||
*
|
||||
@@ -85,9 +88,7 @@ class CouchbaseTemplateSupport implements ApplicationContextAware, TemplateSuppo
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope, String collection) {
|
||||
final CouchbaseDocument converted = new CouchbaseDocument(id);
|
||||
converted.setId(id);
|
||||
public <T> T decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection) {
|
||||
|
||||
// this is the entity class defined for the repository. It may not be the class of the document that was read
|
||||
// we will reset it after reading the document
|
||||
@@ -107,18 +108,32 @@ class CouchbaseTemplateSupport implements ApplicationContextAware, TemplateSuppo
|
||||
// to unwrap. This results in List<String[]> being unwrapped past String[] to String, so this may also be a
|
||||
// Collection (or Array) of entityClass. We have no way of knowing - so just assume it is what we are told.
|
||||
// if this is a Collection or array, only the first element will be returned.
|
||||
final CouchbaseDocument converted = new CouchbaseDocument(id);
|
||||
Set<Map.Entry<String, Object>> set = ((CouchbaseDocument) translationService.decode(source, converted))
|
||||
.getContent().entrySet();
|
||||
return (T) set.iterator().next().getValue();
|
||||
}
|
||||
|
||||
if (id == null) {
|
||||
throw new CouchbaseException(TemplateUtils.SELECT_ID + " was null. Either use #{#n1ql.selectEntity} or project "
|
||||
+ TemplateUtils.SELECT_ID);
|
||||
}
|
||||
|
||||
final CouchbaseDocument converted = new CouchbaseDocument(id);
|
||||
|
||||
// if possible, set the version property in the source so that if the constructor has a long version argument,
|
||||
// it will have a value an not fail (as null is not a valid argument for a long argument). This possible failure
|
||||
// it will have a value and not fail (as null is not a valid argument for a long argument). This possible failure
|
||||
// can be avoid by defining the argument as Long instead of long.
|
||||
// persistentEntity is still the (possibly abstract) class specified in the repository definition
|
||||
// it's possible that the abstract class does not have a version property, and this won't be able to set the version
|
||||
if (cas != 0 && persistentEntity.getVersionProperty() != null) {
|
||||
converted.put(persistentEntity.getVersionProperty().getName(), cas);
|
||||
if (persistentEntity.getVersionProperty() != null) {
|
||||
if (cas == null) {
|
||||
throw new CouchbaseException("version/cas in the entity but " + TemplateUtils.SELECT_CAS
|
||||
+ " was not in result. Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_CAS);
|
||||
}
|
||||
if (cas != 0) {
|
||||
converted.put(persistentEntity.getVersionProperty().getName(), cas);
|
||||
}
|
||||
}
|
||||
|
||||
// if the constructor has an argument that is long version, then construction will fail if the 'version'
|
||||
|
||||
@@ -40,7 +40,7 @@ public class NonReactiveSupportWrapper implements ReactiveTemplateSupport {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<T> decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope,
|
||||
public <T> Mono<T> decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope,
|
||||
String collection) {
|
||||
return Mono.fromSupplier(() -> support.decodeEntity(id, source, cas, entityClass, scope, collection));
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class ReactiveCouchbaseTemplateSupport implements ApplicationContextAware, React
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<T> decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope,
|
||||
public <T> Mono<T> decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope,
|
||||
String collection) {
|
||||
return Mono.fromSupplier(() -> {
|
||||
final CouchbaseDocument converted = new CouchbaseDocument(id);
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.springframework.data.couchbase.core.query.AnalyticsQuery;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.error.CouchbaseException;
|
||||
import com.couchbase.client.java.analytics.AnalyticsOptions;
|
||||
import com.couchbase.client.java.analytics.AnalyticsScanConsistency;
|
||||
import com.couchbase.client.java.analytics.ReactiveAnalyticsResult;
|
||||
@@ -117,23 +116,13 @@ public class ReactiveFindByAnalyticsOperationSupport implements ReactiveFindByAn
|
||||
return throwable;
|
||||
}
|
||||
}).flatMapMany(ReactiveAnalyticsResult::rowsAsObject).flatMap(row -> {
|
||||
String id = "";
|
||||
Long cas = Long.valueOf(0);
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null && row.getString(TemplateUtils.SELECT_ID_3x) == null) {
|
||||
return Flux.error(new CouchbaseException("analytics query did not project " + TemplateUtils.SELECT_ID
|
||||
+ ". Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_ID + " and "
|
||||
+ TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
String id = null;
|
||||
Long cas = null;
|
||||
id = row.getString(TemplateUtils.SELECT_ID);
|
||||
if (id == null) {
|
||||
id = row.getString(TemplateUtils.SELECT_ID_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_ID_3x);
|
||||
}
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null && row.getLong(TemplateUtils.SELECT_CAS_3x) == null) {
|
||||
return Flux.error(new CouchbaseException("analytics query did not project " + TemplateUtils.SELECT_CAS
|
||||
+ ". Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_ID + " and "
|
||||
+ TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS);
|
||||
if (cas == null) {
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS_3x);
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.data.couchbase.core.support.PseudoArgs;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.error.CouchbaseException;
|
||||
import com.couchbase.client.java.query.QueryOptions;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
import com.couchbase.client.java.query.ReactiveQueryResult;
|
||||
@@ -184,24 +183,17 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
|
||||
return throwable;
|
||||
}
|
||||
}).flatMapMany(ReactiveQueryResult::rowsAsObject).flatMap(row -> {
|
||||
String id = "";
|
||||
Long cas = Long.valueOf(0);
|
||||
if (!query.isDistinct() && distinctFields == null) {
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null && row.getString(TemplateUtils.SELECT_ID_3x) == null) {
|
||||
return Flux.error(new CouchbaseException(
|
||||
"query did not project " + TemplateUtils.SELECT_ID + ". Either use #{#n1ql.selectEntity} or project "
|
||||
+ TemplateUtils.SELECT_ID + " and " + TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
String id = null;
|
||||
Long cas = null;
|
||||
if (query.isDistinct() || distinctFields != null) {
|
||||
id = "";
|
||||
cas = Long.valueOf(0);
|
||||
} else {
|
||||
id = row.getString(TemplateUtils.SELECT_ID);
|
||||
if (id == null) {
|
||||
id = row.getString(TemplateUtils.SELECT_ID_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_ID_3x);
|
||||
}
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null && row.getLong(TemplateUtils.SELECT_CAS_3x) == null) {
|
||||
return Flux.error(new CouchbaseException(
|
||||
"query did not project " + TemplateUtils.SELECT_CAS + ". Either use #{#n1ql.selectEntity} or project "
|
||||
+ TemplateUtils.SELECT_ID + " and " + TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS);
|
||||
if (cas == null) {
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS_3x);
|
||||
|
||||
@@ -21,14 +21,13 @@ import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
public interface ReactiveTemplateSupport {
|
||||
|
||||
Mono<CouchbaseDocument> encodeEntity(Object entityToEncode);
|
||||
|
||||
<T> Mono<T> decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope, String collection);
|
||||
<T> Mono<T> decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection);
|
||||
|
||||
<T> Mono<T> applyUpdatedCas(T entity, CouchbaseDocument converted, long cas);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface TemplateSupport {
|
||||
|
||||
CouchbaseDocument encodeEntity(Object entityToEncode);
|
||||
|
||||
<T> T decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope, String collection);
|
||||
<T> T decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection);
|
||||
|
||||
<T> T applyUpdatedCas(T entity, CouchbaseDocument converted, long cas);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user