From 60196095a64ab5b9feaae6a750777b1312c2f860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Basl=C3=A9?= Date: Fri, 31 Jul 2015 17:47:39 +0200 Subject: [PATCH] DATACOUCH-155 - Correctly escape property path. Additionally to resolving a POJO attribute to JSON field name, the path conversion step will also escape each part of the doted path, in order to avoid problems with N1QL keywords. --- .../repository/N1qlCrudRepositoryTests.java | 65 +++++++++++++++++++ .../couchbase/repository/PartyRepository.java | 2 + .../mapping/CouchbasePersistentProperty.java | 15 ----- .../repository/query/N1qlQueryCreator.java | 14 +++- 4 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 src/integration/java/org/springframework/data/couchbase/repository/N1qlCrudRepositoryTests.java diff --git a/src/integration/java/org/springframework/data/couchbase/repository/N1qlCrudRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCrudRepositoryTests.java new file mode 100644 index 00000000..522de35d --- /dev/null +++ b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCrudRepositoryTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.couchbase.repository; + +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import java.util.List; + +import com.couchbase.client.java.Bucket; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.couchbase.IntegrationTestApplicationConfig; +import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Simon Baslé + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = IntegrationTestApplicationConfig.class) +public class N1qlCrudRepositoryTests { + + @Autowired + private Bucket client; + + @Autowired + private CouchbaseTemplate template; + + private PartyRepository partyRepository; + + @Before + public void setup() throws Exception { + partyRepository = new CouchbaseRepositoryFactory(template).getRepository(PartyRepository.class); + } + + @Test + public void shouldSaveObjectWithN1qlKeywordField() { + Party party = new Party("partyHasKeyword", "party", "desc is a N1QL keyword", new Date(), 40); + partyRepository.save(party); + List parties = partyRepository.findAllByDescriptionNotNull(); + + assertTrue(client.exists("partyHasKeyword")); + assertTrue(parties.contains(party)); + } +} 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 0eff1e5f..072a3315 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java @@ -17,4 +17,6 @@ public interface PartyRepository extends CouchbaseRepository { @View(designDocument = "party", viewName = "byDate") List findFirst3ByEventDateGreaterThanEqual(Date targetDate); + List findAllByDescriptionNotNull(); + } diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java index 04c29785..0603de8b 100644 --- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java +++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java @@ -16,9 +16,7 @@ package org.springframework.data.couchbase.core.mapping; -import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.PersistentPropertyPath; /** * Represents a property part of an entity that needs to be persisted. @@ -33,17 +31,4 @@ public interface CouchbasePersistentProperty extends PersistentProperty FIELD_NAME = new Converter() { - @Override - public String convert(CouchbasePersistentProperty source) { - return source.getFieldName(); - } - }; - - } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java index b97caab0..2caee9dc 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java @@ -32,6 +32,7 @@ import com.couchbase.client.java.query.dsl.path.LimitPath; import com.couchbase.client.java.query.dsl.path.OrderByPath; import com.couchbase.client.java.query.dsl.path.WherePath; +import org.springframework.core.convert.converter.Converter; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.domain.Sort; @@ -146,7 +147,7 @@ public class N1qlQueryCreator extends AbstractQueryCreator FIELD_NAME_ESCAPED = new Converter() { + @Override + public String convert(CouchbasePersistentProperty source) { + return "`" + source.getFieldName() + "`"; + } + }; + }