diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java index fa5a39e2d..64c4c777e 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java @@ -37,6 +37,7 @@ 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.util.Assert; import org.springframework.util.ClassUtils; +import com.couchbase.client.core.error.CouchbaseException; + /** * Internal encode/decode support for CouchbaseTemplate. * @@ -85,9 +88,7 @@ public CouchbaseDocument encodeEntity(final Object entityToEncode) { } @Override - public T decodeEntity(String id, String source, long cas, Class entityClass, String scope, String collection) { - final CouchbaseDocument converted = new CouchbaseDocument(id); - converted.setId(id); + public T decodeEntity(String id, String source, Long cas, Class 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 @@ public T decodeEntity(String id, String source, long cas, Class entityCla // to unwrap. This results in List 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> 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' diff --git a/src/main/java/org/springframework/data/couchbase/core/NonReactiveSupportWrapper.java b/src/main/java/org/springframework/data/couchbase/core/NonReactiveSupportWrapper.java index bee19a4a8..7cb19f82d 100644 --- a/src/main/java/org/springframework/data/couchbase/core/NonReactiveSupportWrapper.java +++ b/src/main/java/org/springframework/data/couchbase/core/NonReactiveSupportWrapper.java @@ -40,7 +40,7 @@ public Mono encodeEntity(Object entityToEncode) { } @Override - public Mono decodeEntity(String id, String source, long cas, Class entityClass, String scope, + public Mono decodeEntity(String id, String source, Long cas, Class entityClass, String scope, String collection) { return Mono.fromSupplier(() -> support.decodeEntity(id, source, cas, entityClass, scope, collection)); } diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateSupport.java index 7a500d46c..76026751e 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateSupport.java @@ -85,7 +85,7 @@ public Mono encodeEntity(final Object entityToEncode) { } @Override - public Mono decodeEntity(String id, String source, long cas, Class entityClass, String scope, + public Mono decodeEntity(String id, String source, Long cas, Class entityClass, String scope, String collection) { return Mono.fromSupplier(() -> { final CouchbaseDocument converted = new CouchbaseDocument(id); diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByAnalyticsOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByAnalyticsOperationSupport.java index b8481dcee..87e617b20 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByAnalyticsOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByAnalyticsOperationSupport.java @@ -22,7 +22,6 @@ 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 Flux all() { 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); diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByQueryOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByQueryOperationSupport.java index 03ae5f0d6..1e8197c53 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByQueryOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveFindByQueryOperationSupport.java @@ -25,7 +25,6 @@ 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 Flux all() { 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); diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveTemplateSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveTemplateSupport.java index 0fa725574..69d5db015 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveTemplateSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveTemplateSupport.java @@ -21,14 +21,13 @@ import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent; /** - * * @author Michael Reiche */ public interface ReactiveTemplateSupport { Mono encodeEntity(Object entityToEncode); - Mono decodeEntity(String id, String source, long cas, Class entityClass, String scope, String collection); + Mono decodeEntity(String id, String source, Long cas, Class entityClass, String scope, String collection); Mono applyUpdatedCas(T entity, CouchbaseDocument converted, long cas); diff --git a/src/main/java/org/springframework/data/couchbase/core/TemplateSupport.java b/src/main/java/org/springframework/data/couchbase/core/TemplateSupport.java index 084b1b718..bd5ab0ae9 100644 --- a/src/main/java/org/springframework/data/couchbase/core/TemplateSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/TemplateSupport.java @@ -26,7 +26,7 @@ public interface TemplateSupport { CouchbaseDocument encodeEntity(Object entityToEncode); - T decodeEntity(String id, String source, long cas, Class entityClass, String scope, String collection); + T decodeEntity(String id, String source, Long cas, Class entityClass, String scope, String collection); T applyUpdatedCas(T entity, CouchbaseDocument converted, long cas);