This is an automated email from the ASF dual-hosted git repository. ilyak pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 0eb9b03c IGNITE-13028 Spring Data integration introspects the fields of the key object - Fixes #8328. 0eb9b03c is described below commit 0eb9b03caaa918745ba1bda741bfb26a00fe4276 Author: Ilya Kazakov <kazakov.i...@gmail.com> AuthorDate: Fri Oct 16 12:30:35 2020 +0300 IGNITE-13028 Spring Data integration introspects the fields of the key object - Fixes #8328. Signed-off-by: Ilya Kasnacheev <ilya.kasnach...@gmail.com> --- .../repository/query/IgniteQueryGenerator.java | 29 ++++- .../IgniteSpringDataCompoundKeyTest.java | 125 +++++++++++++++++++++ .../apache/ignite/springdata/compoundkey/City.java | 113 +++++++++++++++++++ .../ignite/springdata/compoundkey/CityKey.java | 76 +++++++++++++ .../springdata/compoundkey/CityRepository.java} | 38 ++++--- .../CompoundKeyApplicationConfiguration.java} | 32 +++--- .../testsuites/IgniteSpringData2TestSuite.java | 4 +- .../repository/query/IgniteQueryGenerator.java | 29 ++++- .../IgniteSpringDataCompoundKeyTest.java | 125 +++++++++++++++++++++ .../apache/ignite/springdata/compoundkey/City.java | 113 +++++++++++++++++++ .../ignite/springdata/compoundkey/CityKey.java | 79 +++++++++++++ .../springdata/compoundkey/CityRepository.java} | 38 ++++--- .../CompoundKeyApplicationConfiguration.java} | 32 +++--- .../testsuites/IgniteSpringData22TestSuite.java | 4 +- .../repository/query/IgniteQueryGenerator.java | 29 ++++- .../IgniteSpringDataCompoundKeyTest.java | 116 +++++++++++++++++++ .../apache/ignite/springdata/compoundkey/City.java | 113 +++++++++++++++++++ .../ignite/springdata/compoundkey/CityKey.java | 79 +++++++++++++ .../compoundkey/CityRepository.java} | 38 ++++--- .../CompoundKeyApplicationConfiguration.java} | 32 +++--- .../testsuites/IgniteSpringDataTestSuite.java | 4 +- 21 files changed, 1146 insertions(+), 102 deletions(-) diff --git a/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java index 98d0bbc..864903a 100644 --- a/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java +++ b/modules/spring-data-2.0/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java @@ -20,6 +20,8 @@ package org.apache.ignite.springdata20.repository.query; import java.lang.reflect.Method; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.PropertyPath; +import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; @@ -39,7 +41,14 @@ public class IgniteQueryGenerator { * @return Generated ignite query. */ public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) { - PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType()); + PartTree parts; + + try { + parts = new PartTree(mtd.getName(), metadata.getDomainType()); + } + catch (PropertyReferenceException e) { + parts = new PartTree(mtd.getName(), metadata.getIdType()); + } boolean isCountOrFieldQuery = parts.isCountProjection(); @@ -72,7 +81,7 @@ public class IgniteQueryGenerator { sql.append("("); for (Part part : orPart) { - handleQueryPart(sql, part); + handleQueryPart(sql, part, metadata.getDomainType()); sql.append(" AND "); } @@ -176,12 +185,24 @@ public class IgniteQueryGenerator { } /** + * Check and correct table name if using column name from compound key. + */ + private static String getColumnName(Part part, Class<?> domainType) { + PropertyPath prperty = part.getProperty(); + + if (prperty.getType() != domainType) + return domainType.getSimpleName() + "." + prperty.getSegment(); + else + return part.toString(); + } + + /** * Transform part to qryStr expression */ - private static void handleQueryPart(StringBuilder sql, Part part) { + private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) { sql.append("("); - sql.append(part.getProperty()); + sql.append(getColumnName(part, domainType)); switch (part.getType()) { case SIMPLE_PROPERTY: diff --git a/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java new file mode 100644 index 0000000..5cad848 --- /dev/null +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.util.Optional; +import org.apache.ignite.Ignite; +import org.apache.ignite.springdata.compoundkey.City; +import org.apache.ignite.springdata.compoundkey.CityKey; +import org.apache.ignite.springdata.compoundkey.CityRepository; +import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * Test with using conpoud key in spring-data + * */ +public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest { + /** Application context */ + private static AnnotationConfigApplicationContext ctx; + + /** City repository */ + private static CityRepository repo; + + /** Cache name */ + private static final String CACHE_NAME = "City"; + + /** Cities count */ + private static final int TOTAL_COUNT = 5; + + /** Count Afganistan cities */ + private static final int AFG_COUNT = 4; + + /** Kabul identifier */ + private static final int KABUL_ID = 1; + + /** Quandahar identifier */ + private static final int QUANDAHAR_ID = 2; + + /** Afganistan county code */ + private static final String AFG = "AFG"; + + /** test city Kabul */ + private static final City KABUL = new City("Kabul", "Kabol", 1780000); + + /** test city Quandahar */ + private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500); + + /** + * Performs context initialization before tests. + */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + ctx = new AnnotationConfigApplicationContext(); + ctx.register(CompoundKeyApplicationConfiguration.class); + ctx.refresh(); + + repo = ctx.getBean(CityRepository.class); + } + + /** + * Load data + * */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + loadData(); + + assertEquals(TOTAL_COUNT, repo.count()); + } + + /** + * Performs context destroy after tests. + */ + @Override protected void afterTestsStopped() { + ctx.close(); + } + + /** load data*/ + public void loadData() throws Exception { + Ignite ignite = ctx.getBean(Ignite.class); + + if (ignite.cacheNames().contains(CACHE_NAME)) + ignite.destroyCache(CACHE_NAME); + + try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/")) { + Statement st = conn.createStatement(); + + st.execute("DROP TABLE IF EXISTS City"); + st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\""); + st.execute("SET STREAMING ON;"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)"); + } + } + + /** Test */ + @Test + public void test() { + assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG))); + assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size()); + assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID)); + } +} diff --git a/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/City.java new file mode 100644 index 0000000..e86a575 --- /dev/null +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/City.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.util.Objects; + +/** + * Value-class + * */ +public class City { + /** City name */ + private String name; + + /** City district */ + private String district; + + /** City population */ + private int population; + + /** + * @param name city name + * @param district city district + * @param population city population + * */ + public City(String name, String district, int population) { + this.name = name; + this.district = district; + this.population = population; + } + + /** + * @return city name + * */ + public String getName() { + return name; + } + + /** + * @param name city name + * */ + public void setName(String name) { + this.name = name; + } + + /** + * @return city district + * */ + public String getDistrict() { + return district; + } + + /** + * @param district city district + * */ + public void setDistrict(String district) { + this.district = district; + } + + /** + * @return city population + * */ + public int getPopulation() { + return population; + } + + /** + * @param population city population + * */ + public void setPopulation(int population) { + this.population = population; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return name + " | " + district + " | " + population; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + City city = (City)o; + + return + Objects.equals(this.name, city.name) && + Objects.equals(this.district, city.district) && + this.population == city.population; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(name, district, population); + } +} diff --git a/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java new file mode 100644 index 0000000..8a5dba0 --- /dev/null +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.cache.affinity.AffinityKeyMapped; + +/** Compound key for city class */ +public class CityKey implements Serializable { + /** city identifier */ + private int ID; + + /** affinity key countrycode */ + @AffinityKeyMapped + private String COUNTRYCODE; + + /** + * @param id city identifier + * @param countryCode city countrycode + * */ + public CityKey(int id, String countryCode) { + this.ID = id; + this.COUNTRYCODE = countryCode; + } + + /** + * @return city id + * */ + public int getId() { + return ID; + } + + /** + * @return countrycode + * */ + public String getCountryCode() { + return COUNTRYCODE; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + CityKey key = (CityKey)o; + return ID == key.ID && + COUNTRYCODE.equals(key.COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(ID, COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return ID + " | " + COUNTRYCODE; + } +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java similarity index 50% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java index 1b6c967..d9adee3 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java @@ -15,21 +15,29 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import java.util.List; +import javax.cache.Cache; +import org.apache.ignite.springdata20.repository.IgniteRepository; +import org.apache.ignite.springdata20.repository.config.RepositoryConfig; +import org.springframework.stereotype.Repository; -/** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { -} +/** City repository */ +@Repository +@RepositoryConfig(cacheName = "City", autoCreateCache = true) +public interface CityRepository extends IgniteRepository<City, CityKey> { + /** + * Find city by id + * @param id city identifier + * @return city + * */ + public City findById(int id); + /** + * Find all cities by coutrycode + * @param cc coutrycode + * @return list of cache enrties CityKey -> City + * */ + public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc); +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java similarity index 58% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java index 1b6c967..91fe894 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java @@ -15,21 +15,25 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.apache.ignite.Ignite; +import org.apache.ignite.Ignition; +import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; /** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { + * Spring application configuration + * */ +@Configuration +@EnableIgniteRepositories +public class CompoundKeyApplicationConfiguration { + /** + * Ignite instance bean + * */ + @Bean + public Ignite igniteInstance() { + return Ignition.start(); + } } - diff --git a/modules/spring-data-2.0/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java b/modules/spring-data-2.0/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java index fdfbbb8..4efc48b1 100644 --- a/modules/spring-data-2.0/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java +++ b/modules/spring-data-2.0/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java @@ -17,6 +17,7 @@ package org.apache.ignite.testsuites; +import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest; import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest; import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; @@ -30,7 +31,8 @@ import org.junit.runners.Suite; @Suite.SuiteClasses({ IgniteSpringDataCrudSelfTest.class, IgniteSpringDataQueriesSelfTest.class, - IgniteSpringDataCrudSelfExpressionTest.class + IgniteSpringDataCrudSelfExpressionTest.class, + IgniteSpringDataCompoundKeyTest.class }) public class IgniteSpringData2TestSuite { } diff --git a/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java index 11d9e81..a0be11d 100644 --- a/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java +++ b/modules/spring-data-2.2/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java @@ -20,6 +20,8 @@ package org.apache.ignite.springdata22.repository.query; import java.lang.reflect.Method; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.PropertyPath; +import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; @@ -39,7 +41,14 @@ public class IgniteQueryGenerator { * @return Generated ignite query. */ public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) { - PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType()); + PartTree parts; + + try { + parts = new PartTree(mtd.getName(), metadata.getDomainType()); + } + catch (PropertyReferenceException e) { + parts = new PartTree(mtd.getName(), metadata.getIdType()); + } boolean isCountOrFieldQuery = parts.isCountProjection(); @@ -72,7 +81,7 @@ public class IgniteQueryGenerator { sql.append("("); for (Part part : orPart) { - handleQueryPart(sql, part); + handleQueryPart(sql, part, metadata.getDomainType()); sql.append(" AND "); } @@ -176,12 +185,24 @@ public class IgniteQueryGenerator { } /** + * Check and correct table name if using column name from compound key. + */ + private static String getColumnName(Part part, Class<?> domainType) { + PropertyPath prperty = part.getProperty(); + + if (prperty.getType() != domainType) + return domainType.getSimpleName() + "." + prperty.getSegment(); + else + return part.toString(); + } + + /** * Transform part to qryStr expression */ - private static void handleQueryPart(StringBuilder sql, Part part) { + private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) { sql.append("("); - sql.append(part.getProperty()); + sql.append(getColumnName(part, domainType)); switch (part.getType()) { case SIMPLE_PROPERTY: diff --git a/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java new file mode 100644 index 0000000..5cad848 --- /dev/null +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.util.Optional; +import org.apache.ignite.Ignite; +import org.apache.ignite.springdata.compoundkey.City; +import org.apache.ignite.springdata.compoundkey.CityKey; +import org.apache.ignite.springdata.compoundkey.CityRepository; +import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * Test with using conpoud key in spring-data + * */ +public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest { + /** Application context */ + private static AnnotationConfigApplicationContext ctx; + + /** City repository */ + private static CityRepository repo; + + /** Cache name */ + private static final String CACHE_NAME = "City"; + + /** Cities count */ + private static final int TOTAL_COUNT = 5; + + /** Count Afganistan cities */ + private static final int AFG_COUNT = 4; + + /** Kabul identifier */ + private static final int KABUL_ID = 1; + + /** Quandahar identifier */ + private static final int QUANDAHAR_ID = 2; + + /** Afganistan county code */ + private static final String AFG = "AFG"; + + /** test city Kabul */ + private static final City KABUL = new City("Kabul", "Kabol", 1780000); + + /** test city Quandahar */ + private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500); + + /** + * Performs context initialization before tests. + */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + ctx = new AnnotationConfigApplicationContext(); + ctx.register(CompoundKeyApplicationConfiguration.class); + ctx.refresh(); + + repo = ctx.getBean(CityRepository.class); + } + + /** + * Load data + * */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + loadData(); + + assertEquals(TOTAL_COUNT, repo.count()); + } + + /** + * Performs context destroy after tests. + */ + @Override protected void afterTestsStopped() { + ctx.close(); + } + + /** load data*/ + public void loadData() throws Exception { + Ignite ignite = ctx.getBean(Ignite.class); + + if (ignite.cacheNames().contains(CACHE_NAME)) + ignite.destroyCache(CACHE_NAME); + + try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/")) { + Statement st = conn.createStatement(); + + st.execute("DROP TABLE IF EXISTS City"); + st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\""); + st.execute("SET STREAMING ON;"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)"); + } + } + + /** Test */ + @Test + public void test() { + assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG))); + assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size()); + assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID)); + } +} diff --git a/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/City.java new file mode 100644 index 0000000..e86a575 --- /dev/null +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/City.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.util.Objects; + +/** + * Value-class + * */ +public class City { + /** City name */ + private String name; + + /** City district */ + private String district; + + /** City population */ + private int population; + + /** + * @param name city name + * @param district city district + * @param population city population + * */ + public City(String name, String district, int population) { + this.name = name; + this.district = district; + this.population = population; + } + + /** + * @return city name + * */ + public String getName() { + return name; + } + + /** + * @param name city name + * */ + public void setName(String name) { + this.name = name; + } + + /** + * @return city district + * */ + public String getDistrict() { + return district; + } + + /** + * @param district city district + * */ + public void setDistrict(String district) { + this.district = district; + } + + /** + * @return city population + * */ + public int getPopulation() { + return population; + } + + /** + * @param population city population + * */ + public void setPopulation(int population) { + this.population = population; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return name + " | " + district + " | " + population; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + City city = (City)o; + + return + Objects.equals(this.name, city.name) && + Objects.equals(this.district, city.district) && + this.population == city.population; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(name, district, population); + } +} diff --git a/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java new file mode 100644 index 0000000..88226fee --- /dev/null +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.cache.affinity.AffinityKeyMapped; + +/** Compound key for city class */ +public class CityKey implements Serializable { + /** city identifier */ + private int ID; + + /** affinity key countrycode */ + @AffinityKeyMapped + private String COUNTRYCODE; + + /** + * @param id city identifier + * @param countryCode city countrycode + * */ + public CityKey(int id, String countryCode) { + this.ID = id; + this.COUNTRYCODE = countryCode; + } + + /** + * @return city id + * */ + public int getId() { + return ID; + } + + /** + * @return countrycode + * */ + public String getCountryCode() { + return COUNTRYCODE; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + CityKey key = (CityKey)o; + + return ID == key.ID && + COUNTRYCODE.equals(key.COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(ID, COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return ID + " | " + COUNTRYCODE; + } +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java similarity index 50% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java index 1b6c967..ab745e7 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java @@ -15,21 +15,29 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import java.util.List; +import javax.cache.Cache; +import org.apache.ignite.springdata22.repository.IgniteRepository; +import org.apache.ignite.springdata22.repository.config.RepositoryConfig; +import org.springframework.stereotype.Repository; -/** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { -} +/** City repository */ +@Repository +@RepositoryConfig(cacheName = "City", autoCreateCache = true) +public interface CityRepository extends IgniteRepository<City, CityKey> { + /** + * Find city by id + * @param id city identifier + * @return city + * */ + public City findById(int id); + /** + * Find all cities by coutrycode + * @param cc coutrycode + * @return list of cache enrties CityKey -> City + * */ + public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc); +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java similarity index 58% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java index 1b6c967..7b6ff16 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java @@ -15,21 +15,25 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.apache.ignite.Ignite; +import org.apache.ignite.Ignition; +import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; /** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { + * Spring application configuration + * */ +@Configuration +@EnableIgniteRepositories +public class CompoundKeyApplicationConfiguration { + /** + * Ignite instance bean + * */ + @Bean + public Ignite igniteInstance() { + return Ignition.start(); + } } - diff --git a/modules/spring-data-2.2/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java b/modules/spring-data-2.2/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java index 0e896f6..872fe9f 100644 --- a/modules/spring-data-2.2/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java +++ b/modules/spring-data-2.2/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java @@ -17,6 +17,7 @@ package org.apache.ignite.testsuites; +import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest; import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest; import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; @@ -30,7 +31,8 @@ import org.junit.runners.Suite; @Suite.SuiteClasses({ IgniteSpringDataCrudSelfTest.class, IgniteSpringDataQueriesSelfTest.class, - IgniteSpringDataCrudSelfExpressionTest.class + IgniteSpringDataCrudSelfExpressionTest.class, + IgniteSpringDataCompoundKeyTest.class }) public class IgniteSpringData22TestSuite { } diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java index 3fe0780..e1f3f2f 100644 --- a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java +++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java @@ -21,6 +21,8 @@ import java.lang.reflect.Method; import org.jetbrains.annotations.NotNull; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.PropertyPath; +import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; @@ -35,7 +37,14 @@ public class IgniteQueryGenerator { * @param metadata Metadata. */ @NotNull public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) { - PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType()); + PartTree parts; + + try { + parts = new PartTree(mtd.getName(), metadata.getDomainType()); + } + catch (PropertyReferenceException e) { + parts = new PartTree(mtd.getName(), metadata.getIdType()); + } StringBuilder sql = new StringBuilder(); @@ -61,7 +70,7 @@ public class IgniteQueryGenerator { for (PartTree.OrPart orPart : parts) { sql.append("("); for (Part part : orPart) { - handleQueryPart(sql, part); + handleQueryPart(sql, part, metadata.getDomainType()); sql.append(" AND "); } @@ -162,12 +171,24 @@ public class IgniteQueryGenerator { } /** + * Check and correct table name if using column name from compound key. + */ + private static String getColumnName(Part part, Class<?> domainType) { + PropertyPath prperty = part.getProperty(); + + if (prperty.getType() != domainType) + return domainType.getSimpleName() + "." + prperty.getSegment(); + else + return part.toString(); + } + + /** * Transform part to sql expression */ - private static void handleQueryPart(StringBuilder sql, Part part) { + private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) { sql.append("("); - sql.append(part.getProperty()); + sql.append(getColumnName(part, domainType)); switch (part.getType()) { case SIMPLE_PROPERTY: diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java new file mode 100644 index 0000000..afc24cb --- /dev/null +++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import org.apache.ignite.Ignite; +import org.apache.ignite.springdata.compoundkey.City; +import org.apache.ignite.springdata.compoundkey.CityRepository; +import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * Test with using conpoud key in spring-data + * */ +public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest { + /** Application context */ + private static AnnotationConfigApplicationContext ctx; + + /** City repository */ + private static CityRepository repo; + + /** Cache name */ + private static final String CACHE_NAME = "City"; + + /** Cities count */ + private static final int TOTAL_COUNT = 5; + + /** Count Afganistan cities */ + private static final int AFG_COUNT = 4; + + /** Quandahar identifier */ + private static final int QUANDAHAR_ID = 2; + + /** Afganistan county code */ + private static final String AFG = "AFG"; + + /** test city Quandahar */ + private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500); + + /** + * Performs context initialization before tests. + */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + ctx = new AnnotationConfigApplicationContext(); + ctx.register(CompoundKeyApplicationConfiguration.class); + ctx.refresh(); + + repo = ctx.getBean(CityRepository.class); + } + + /** + * Load data + * */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + loadData(); + + assertEquals(TOTAL_COUNT, repo.count()); + } + + /** + * Performs context destroy after tests. + */ + @Override protected void afterTestsStopped() { + ctx.close(); + } + + /** load data*/ + public void loadData() throws Exception { + Ignite ignite = ctx.getBean(Ignite.class); + + if (ignite.cacheNames().contains(CACHE_NAME)) + ignite.destroyCache(CACHE_NAME); + + try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/")) { + Statement st = conn.createStatement(); + + st.execute("DROP TABLE IF EXISTS City"); + st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\""); + st.execute("SET STREAMING ON;"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)"); + st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)"); + } + } + + /** Test */ + @Test + public void test() { + assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size()); + assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID)); + } +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/City.java new file mode 100644 index 0000000..e86a575 --- /dev/null +++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/City.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.util.Objects; + +/** + * Value-class + * */ +public class City { + /** City name */ + private String name; + + /** City district */ + private String district; + + /** City population */ + private int population; + + /** + * @param name city name + * @param district city district + * @param population city population + * */ + public City(String name, String district, int population) { + this.name = name; + this.district = district; + this.population = population; + } + + /** + * @return city name + * */ + public String getName() { + return name; + } + + /** + * @param name city name + * */ + public void setName(String name) { + this.name = name; + } + + /** + * @return city district + * */ + public String getDistrict() { + return district; + } + + /** + * @param district city district + * */ + public void setDistrict(String district) { + this.district = district; + } + + /** + * @return city population + * */ + public int getPopulation() { + return population; + } + + /** + * @param population city population + * */ + public void setPopulation(int population) { + this.population = population; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return name + " | " + district + " | " + population; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + City city = (City)o; + + return + Objects.equals(this.name, city.name) && + Objects.equals(this.district, city.district) && + this.population == city.population; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(name, district, population); + } +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java new file mode 100644 index 0000000..88226fee --- /dev/null +++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ignite.springdata.compoundkey; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.cache.affinity.AffinityKeyMapped; + +/** Compound key for city class */ +public class CityKey implements Serializable { + /** city identifier */ + private int ID; + + /** affinity key countrycode */ + @AffinityKeyMapped + private String COUNTRYCODE; + + /** + * @param id city identifier + * @param countryCode city countrycode + * */ + public CityKey(int id, String countryCode) { + this.ID = id; + this.COUNTRYCODE = countryCode; + } + + /** + * @return city id + * */ + public int getId() { + return ID; + } + + /** + * @return countrycode + * */ + public String getCountryCode() { + return COUNTRYCODE; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + CityKey key = (CityKey)o; + + return ID == key.ID && + COUNTRYCODE.equals(key.COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(ID, COUNTRYCODE); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return ID + " | " + COUNTRYCODE; + } +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java similarity index 51% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java index 1b6c967..691fe8e 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java @@ -15,21 +15,29 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import java.util.List; +import javax.cache.Cache; +import org.apache.ignite.springdata.repository.IgniteRepository; +import org.apache.ignite.springdata.repository.config.RepositoryConfig; +import org.springframework.stereotype.Repository; -/** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { -} +/** City repository */ +@Repository +@RepositoryConfig(cacheName = "City") +public interface CityRepository extends IgniteRepository<City, CityKey> { + /** + * Find city by id + * @param id city identifier + * @return city + * */ + public City findById(int id); + /** + * Find all cities by coutrycode + * @param cc coutrycode + * @return list of cache enrties CityKey -> City + * */ + public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc); +} diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java similarity index 58% copy from modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java copy to modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java index 1b6c967..db2dab4 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java @@ -15,21 +15,25 @@ * limitations under the License. */ -package org.apache.ignite.testsuites; +package org.apache.ignite.springdata.compoundkey; -import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; -import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.apache.ignite.Ignite; +import org.apache.ignite.Ignition; +import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; /** - * Ignite Spring Data test suite. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class -}) -public class IgniteSpringDataTestSuite { + * Spring application configuration + * */ +@Configuration +@EnableIgniteRepositories +public class CompoundKeyApplicationConfiguration { + /** + * Ignite instance bean + * */ + @Bean + public Ignite igniteInstance() { + return Ignition.start(); + } } - diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java index 1b6c967..cc063a6 100644 --- a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java +++ b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java @@ -17,6 +17,7 @@ package org.apache.ignite.testsuites; +import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest; import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest; import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest; import org.junit.runner.RunWith; @@ -28,7 +29,8 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ IgniteSpringDataCrudSelfTest.class, - IgniteSpringDataQueriesSelfTest.class + IgniteSpringDataQueriesSelfTest.class, + IgniteSpringDataCompoundKeyTest.class }) public class IgniteSpringDataTestSuite { }