diff --git a/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java index 988a21fbe..1133e31fe 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java @@ -195,4 +195,10 @@ public void testDeleteQuery() { assertTrue(partyList.size() == 1); } + @Test + public void testN1qlMetaPropertyConstructionInPartTree() { + partyRepository.save(new Party("testN1qlMetaPropertyConstructionInPartTree", "", "", null, 0, null)); + List parties = partyRepository.findByKeyLike("%Meta%"); + assertTrue("Party ids contain substring party", parties.size() >= 1); + } } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java index 8c0d9beb1..4993c4407 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java @@ -89,4 +89,6 @@ public interface PartyRepository extends CouchbaseRepository { List findByDescriptionOrName(String description, String name); List removeByDescriptionOrName(String description, String name); + + List findByKeyLike(String key); } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java index 05459472c..3ad9d7758 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java @@ -18,6 +18,7 @@ import static org.junit.Assert.*; +import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -123,4 +124,11 @@ public void testPartTreeQuery() { long count = partyRepository.countAllByDescriptionNotNull().block(); assertEquals("Test N1QL part tree based query", 15, count); } + + @Test + public void testN1qlMetaPropertyConstructionInPartTree() { + partyRepository.save(new Party("reactiveTestN1qlMetaPropertyConstructionInPartTree", "", "", null, 0, null)).block(); + List parties = partyRepository.findByKeyLike("%Meta%").collectList().block(); + assertTrue("Party ids contain substring party", parties.size() >= 1); + } } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java index 4a5605067..bd3d04c6a 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java @@ -57,4 +57,5 @@ public interface ReactivePartyRepository extends ReactiveCouchbaseRepository findByDescriptionOrName(String description, String name); + Flux findByKeyLike(String key); } diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentProperty.java b/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentProperty.java index 6e756fdc9..8eba953a7 100644 --- a/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentProperty.java +++ b/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentProperty.java @@ -43,6 +43,8 @@ public class BasicCouchbasePersistentProperty implements CouchbasePersistentProperty { private final FieldNamingStrategy fieldNamingStrategy; + private final String ID_FIELD_NAME = "id"; + private final String VERSION_FIELD_NAME = "cas"; /** * Create a new instance of the BasicCouchbasePersistentProperty class. @@ -75,6 +77,10 @@ protected Association createAssociation() { */ @Override public String getFieldName() { + + if (isIdProperty() && getOwner().getIdProperty().equals(this)) return ID_FIELD_NAME; + if (isVersionProperty()) return VERSION_FIELD_NAME; + com.couchbase.client.java.repository.annotation.Field annotation = getField(). getAnnotation(com.couchbase.client.java.repository.annotation.Field.class); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/support/N1qlUtils.java b/src/main/java/org/springframework/data/couchbase/repository/query/support/N1qlUtils.java index 78e733e32..b469e82d2 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/support/N1qlUtils.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/support/N1qlUtils.java @@ -24,7 +24,10 @@ import static org.springframework.data.couchbase.core.support.TemplateUtils.*; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.springframework.core.convert.converter.Converter; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; @@ -60,18 +63,15 @@ * @author Mark Paluch */ public class N1qlUtils { + //As per https://docs.couchbase.com/server/5.5/n1ql/n1ql-language-reference/indexing-meta-info.html + final static Set META_PROPERTIES = new HashSet<>(Arrays.asList("id", "expiration", "cas")); /** * A converter that can be used to extract the {@link CouchbasePersistentProperty#getFieldName() fieldName}, * eg. when one wants a path from {@link PersistentPropertyPath#toDotPath(Converter)} made of escaped field names. */ public static final Converter FIELD_NAME_ESCAPED = - new Converter() { - @Override - public String convert(CouchbasePersistentProperty source) { - return "`" + source.getFieldName() + "`"; - } - }; + (source) -> META_PROPERTIES.contains(source.getFieldName()) ? "META()." + source.getFieldName() : "`" + source.getFieldName() + "`"; /** * Escape the given bucketName and produce an {@link Expression}.