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 {
 }

Reply via email to