http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/platforms/dotnet/Apache.Ignite.dxg
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.dxg 
b/modules/platforms/dotnet/Apache.Ignite.dxg
index 012a1eb..806db33 100644
--- a/modules/platforms/dotnet/Apache.Ignite.dxg
+++ b/modules/platforms/dotnet/Apache.Ignite.dxg
@@ -14,7 +14,7 @@
 # Values that contain spaces should be placed between quotes (\" \").
 
 #---------------------------------------------------------------------------
-# Project related configuration options
+# Project related configuration option
 #---------------------------------------------------------------------------
 
 # This tag specifies the encoding used for all characters in the config file
@@ -398,7 +398,7 @@ TYPEDEF_HIDES_STRUCT   = NO
 LOOKUP_CACHE_SIZE      = 0
 
 #---------------------------------------------------------------------------
-# Build related configuration options
+# Build related configuration option
 #---------------------------------------------------------------------------
 
 # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
@@ -690,7 +690,7 @@ LAYOUT_FILE            =
 CITE_BIB_FILES         =
 
 #---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
+# Configuration option related to warning and progress messages
 #---------------------------------------------------------------------------
 
 # The QUIET tag can be used to turn on/off the messages that are generated to
@@ -749,7 +749,7 @@ WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the input files
+# Configuration option related to the input files
 #---------------------------------------------------------------------------
 
 # The INPUT tag is used to specify the files and/or directories that contain
@@ -897,7 +897,7 @@ FILTER_SOURCE_PATTERNS =
 USE_MDFILE_AS_MAINPAGE =
 
 #---------------------------------------------------------------------------
-# Configuration options related to source browsing
+# Configuration option related to source browsing
 #---------------------------------------------------------------------------
 
 # If the SOURCE_BROWSER tag is set to YES then a list of source files will be
@@ -994,7 +994,7 @@ VERBATIM_HEADERS       = YES
 CLANG_ASSISTED_PARSING = NO
 
 # If clang assisted parsing is enabled you can provide the compiler with 
command
-# line options that you would normally use when invoking the compiler. Note 
that
+# line option that you would normally use when invoking the compiler. Note that
 # the include paths will already be set by doxygen for the files and 
directories
 # specified with INPUT and INCLUDE_PATH.
 # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
@@ -1002,7 +1002,7 @@ CLANG_ASSISTED_PARSING = NO
 CLANG_OPTIONS          =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
+# Configuration option related to the alphabetical class index
 #---------------------------------------------------------------------------
 
 # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
@@ -1028,7 +1028,7 @@ COLS_IN_ALPHA_INDEX    = 5
 IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the HTML output
+# Configuration option related to the HTML output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
@@ -1056,7 +1056,7 @@ HTML_FILE_EXTENSION    = .html
 # standard header.
 #
 # To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used 
(e.g.
+# that doxygen needs, which is dependent on the configuration option used (e.g.
 # the setting GENERATE_TREEVIEW). It is highly recommended to start with a
 # default header using
 # doxygen -w html new_header.html new_footer.html new_stylesheet.css
@@ -1496,7 +1496,7 @@ MATHJAX_CODEFILE       =
 # <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
 # key> to jump into the search results window, the results can be navigated
 # using the <cursor keys>. Press <Enter> to select an item or <escape> to 
cancel
-# the search. The filter options can be selected when the cursor is inside the
+# the search. The filter option can be selected when the cursor is inside the
 # search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
 # to select a filter and <Enter> or <escape> to activate or cancel the filter
 # option.
@@ -1571,7 +1571,7 @@ EXTERNAL_SEARCH_ID     =
 EXTRA_SEARCH_MAPPINGS  =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
+# Configuration option related to the LaTeX output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
@@ -1729,7 +1729,7 @@ LATEX_SOURCE_CODE      = NO
 LATEX_BIB_STYLE        = plain
 
 #---------------------------------------------------------------------------
-# Configuration options related to the RTF output
+# Configuration option related to the RTF output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
@@ -1795,7 +1795,7 @@ RTF_EXTENSIONS_FILE    =
 RTF_SOURCE_CODE        = NO
 
 #---------------------------------------------------------------------------
-# Configuration options related to the man page output
+# Configuration option related to the man page output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
@@ -1839,7 +1839,7 @@ MAN_SUBDIR             =
 MAN_LINKS              = NO
 
 #---------------------------------------------------------------------------
-# Configuration options related to the XML output
+# Configuration option related to the XML output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
@@ -1866,7 +1866,7 @@ XML_OUTPUT             = xml
 XML_PROGRAMLISTING     = YES
 
 #---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
+# Configuration option related to the DOCBOOK output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook 
files
@@ -1893,7 +1893,7 @@ DOCBOOK_OUTPUT         = docbook
 DOCBOOK_PROGRAMLISTING = NO
 
 #---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
+# Configuration option for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
@@ -1905,7 +1905,7 @@ DOCBOOK_PROGRAMLISTING = NO
 GENERATE_AUTOGEN_DEF   = NO
 
 #---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
+# Configuration option related to the Perl module output
 #---------------------------------------------------------------------------
 
 # If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl 
module
@@ -1943,7 +1943,7 @@ PERLMOD_PRETTY         = YES
 PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration option related to the preprocessor
 #---------------------------------------------------------------------------
 
 # If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
@@ -2021,7 +2021,7 @@ EXPAND_AS_DEFINED      =
 SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
-# Configuration options related to external references
+# Configuration option related to external references
 #---------------------------------------------------------------------------
 
 # The TAGFILES tag can be used to specify one or more tag files. For each tag
@@ -2073,7 +2073,7 @@ EXTERNAL_PAGES         = YES
 PERL_PATH              = /usr/bin/perl
 
 #---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration option related to the dot tool
 #---------------------------------------------------------------------------
 
 # If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class 
diagram
@@ -2110,7 +2110,7 @@ HIDE_UNDOC_RELATIONS   = YES
 # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
 # available from the path. This tool is part of Graphviz (see:
 # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
+# Bell Labs. The other option in this section have no effect if this option is
 # set to NO
 # The default value is: NO.
 
@@ -2357,7 +2357,7 @@ MAX_DOT_GRAPH_DEPTH    = 0
 DOT_TRANSPARENT        = NO
 
 # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
+# files in one run (i.e. multiple -o and -T option on the command line). This
 # makes dot run faster, but since only newer versions of dot (>1.8.10) support
 # this, this feature is disabled by default.
 # The default value is: NO.

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/platforms/dotnet/build.ps1
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/build.ps1 
b/modules/platforms/dotnet/build.ps1
index 4b5d937..a6b782c 100644
--- a/modules/platforms/dotnet/build.ps1
+++ b/modules/platforms/dotnet/build.ps1
@@ -49,7 +49,7 @@ Build platform ("Any CPU", "x86", "x64").
 Build configuration ("Release", "Debug").
 
 .PARAMETER mavenOpts
-Custom Maven options, default is "-U 
-P-lgpl,-scala,-examples,-test,-benchmarks -Dmaven.javadoc.skip=true".
+Custom Maven option, default is "-U -P-lgpl,-scala,-examples,-test,-benchmarks 
-Dmaven.javadoc.skip=true".
 
 .EXAMPLE
 .\build.ps1 -clean  

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/scalar/src/test/resources/spring-ping-pong-partner.xml
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/resources/spring-ping-pong-partner.xml 
b/modules/scalar/src/test/resources/spring-ping-pong-partner.xml
index 766d9fb..643bc16 100644
--- a/modules/scalar/src/test/resources/spring-ping-pong-partner.xml
+++ b/modules/scalar/src/test/resources/spring-ping-pong-partner.xml
@@ -63,8 +63,8 @@
             <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
                     <!--
-                        Ignite provides several options for automatic 
discovery that can be used
-                        instead os static IP based discovery. For information 
on all options refer
+                        Ignite provides several option for automatic discovery 
that can be used
+                        instead os static IP based discovery. For information 
on all option refer
                         to our documentation: 
http://apacheignite.readme.io/docs/cluster-config
                     -->
                     <!-- Uncomment static IP finder to enable static-based 
discovery of initial nodes. -->

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spring-data/pom.xml b/modules/spring-data/pom.xml
index 6cce90a..5954760 100644
--- a/modules/spring-data/pom.xml
+++ b/modules/spring-data/pom.xml
@@ -42,9 +42,22 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-indexing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-log4j</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
-            <version>${spring.version}</version>
+            <version>4.3.7.RELEASE</version>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java
index bd299a9..ff5b727 100644
--- 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java
@@ -185,7 +185,7 @@ public class IgniteKeyValueAdapter extends 
AbstractKeyValueAdapter {
         if (!keyspace.getClass().equals(String.class))
             throw new IgniteException("Keyspace must be of String type");
 
-        return ignite.cache((String)keyspace);
+        return ignite.getOrCreateCache((String)keyspace);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/Query.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/Query.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/Query.java
new file mode 100644
index 0000000..08b7266
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/Query.java
@@ -0,0 +1,37 @@
+/*
+ * 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.repository;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to provide a user defined SQL query for a method.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Query {
+    /**
+     * SQL query text string.
+     */
+    String value() default "";
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
index 0705e88..1b18e4d 100644
--- 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
@@ -22,6 +22,8 @@ import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import 
org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.support.SimpleIgniteRepository;
 import org.springframework.beans.factory.FactoryBean;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.ComponentScan.Filter;
@@ -39,15 +41,12 @@ import 
org.springframework.data.repository.query.QueryLookupStrategy.Key;
 /**
  * Annotation to activate Apache Ignite repositories. If no base package is 
configured through either {@link #value()},
  * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger 
scanning of the package of annotated class.
- *
- * TODO: replace QueryCreatorType with Ignite version of the querying engine.
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Inherited
 @Import(IgniteRepositoriesRegistar.class)
-@QueryCreatorType(value = SpelQueryCreator.class, repositoryQueryType = 
CachingKeyValuePartTreeQuery.class)
 public @interface EnableIgniteRepositories {
     /**
      * Alias for the {@link #basePackages()} attribute. Allows for more 
concise annotation declarations e.g.:
@@ -106,20 +105,19 @@ public @interface EnableIgniteRepositories {
     Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
 
     /**
-     * TODO: replace with Ignite factory bean.
      * Returns the {@link FactoryBean} class to be used for each repository 
instance. Defaults to
-     * {@link KeyValueRepositoryFactoryBean}.
+     * {@link IgniteRepositoryFactoryBean}.
      *
      * @return
      */
-    Class<?> repositoryFactoryBeanClass() default 
KeyValueRepositoryFactoryBean.class;
+    Class<?> repositoryFactoryBeanClass() default 
IgniteRepositoryFactoryBean.class;
 
     /**
      * Configure the repository base class to be used to create repository 
proxies for this particular configuration.
      *
      * @return
      */
-    Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;
+    Class<?> repositoryBaseClass() default SimpleIgniteRepository.class;
 
     /**
      * Configures the name of the {@link KeyValueOperations} bean to be used 
with the repositories detected.

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
index 30f9385..9c2965c 100644
--- 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
@@ -16,6 +16,10 @@
  */
 package org.apache.ignite.springdata.repository.config;
 
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import 
org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
 import 
org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
 import 
org.springframework.data.repository.config.RepositoryConfigurationExtension;
 
@@ -37,4 +41,14 @@ public class IgniteRepositoryConfigurationExtension extends 
KeyValueRepositoryCo
     @Override protected String getDefaultKeyValueTemplateRef() {
         return "igniteKeyValueTemplate";
     }
+
+    /** {@inheritDoc} */
+    @Override public String getRepositoryFactoryClassName() {
+        return IgniteRepositoryFactoryBean.class.getName();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Collection<Class<?>> getIdentifyingTypes() {
+        return Collections.<Class<?>>singleton(IgniteRepository.class);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
new file mode 100644
index 0000000..b30ef2e
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
@@ -0,0 +1,39 @@
+/*
+ * 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.repository.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The annotation can be used to pass Ignite specific parameters to a bound 
repository.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface RepositoryConfig {
+    /**
+     * @return A name of a distributed Apache Ignite cache the repository will 
be mapped to.
+     */
+    String cacheName() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
new file mode 100644
index 0000000..f630ca0
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
@@ -0,0 +1,83 @@
+/*
+ * 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.repository.query;
+
+/**
+ * Ignite query helper class. For internal use only.
+ */
+public class IgniteQuery {
+    /** */
+    enum Option {
+        /** Query will be used with Sort object. */
+        SORTING,
+
+        /** Query will be used with Pageable object. */
+        PAGINATION,
+
+        /** No advanced option. */
+        NONE
+    }
+
+    /** Sql query text string. */
+    private final String sql;
+
+    /** */
+    private final boolean isFieldQuery;
+
+    /** Type of option. */
+    private final Option option;
+
+    /**
+     * @param sql Sql.
+     * @param isFieldQuery Is field query.
+     * @param option Option.
+     */
+    public IgniteQuery(String sql, boolean isFieldQuery, Option option) {
+        this.sql = sql;
+        this.isFieldQuery = isFieldQuery;
+        this.option = option;
+    }
+
+    /**
+     * Text string of the query.
+     *
+     * @return SQL query text string.
+     */
+    public String sql() {
+        return sql;
+    }
+
+    /**
+     * Returns {@code true} if it's Ignite SQL fields query, {@code false} 
otherwise.
+     *
+     * @return {@code true} if it's Ignite SQL fields query, {@code false} 
otherwise.
+     */
+    public boolean isFieldQuery() {
+        return isFieldQuery;
+    }
+
+    /**
+     * Advanced querying option.
+     *
+     * @return querying option.
+     */
+    public Option options() {
+        return option;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..2db2789
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
@@ -0,0 +1,243 @@
+/*
+ * 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.repository.query;
+
+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.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.parser.Part;
+import org.springframework.data.repository.query.parser.PartTree;
+
+/**
+ * Ignite query generator for Spring Data framework.
+ */
+public class IgniteQueryGenerator {
+
+    /**
+     * @param mtd Method.
+     * @param metadata Metadata.
+     */
+    @NotNull public static IgniteQuery generateSql(Method mtd, 
RepositoryMetadata metadata) {
+        PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType());
+
+        StringBuilder sql = new StringBuilder();
+
+        if (parts.isDelete())
+            throw new UnsupportedOperationException("DELETE clause is not 
supported now.");
+        else {
+            sql.append("SELECT ");
+
+            if (parts.isDistinct())
+                throw new UnsupportedOperationException("DISTINCT clause in 
not supported.");
+
+            if (parts.isCountProjection())
+                sql.append("COUNT(1) ");
+            else
+                sql.append(" * ");
+        }
+
+        sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
+
+        if (parts.iterator().hasNext()) {
+            sql.append(" WHERE ");
+
+            for (PartTree.OrPart orPart : parts) {
+                sql.append("(");
+                for (Part part : orPart) {
+                    handleQueryPart(sql, part);
+                    sql.append(" AND ");
+                }
+
+                sql.delete(sql.length() - 5, sql.length());
+
+                sql.append(") OR ");
+            }
+
+            sql.delete(sql.length() - 4, sql.length());
+        }
+
+        addSorting(sql, parts.getSort());
+
+        if (parts.isLimiting()) {
+            sql.append(" LIMIT ");
+            sql.append(parts.getMaxResults().intValue());
+        }
+
+        return new IgniteQuery(sql.toString(), parts.isCountProjection(), 
getOptions(mtd));
+    }
+
+    /**
+     * Add a dynamic part of query for the sorting support.
+     *
+     * @param sql SQL text string.
+     * @param sort Sort method.
+     */
+    public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
+        if (sort != null) {
+            sql.append(" ORDER BY ");
+
+            for (Sort.Order order : sort) {
+                sql.append(order.getProperty()).append(" 
").append(order.getDirection());
+
+                if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
+                    sql.append(" ").append("NULL ");
+                    switch (order.getNullHandling()) {
+                        case NULLS_FIRST:
+                            sql.append("FIRST");
+                            break;
+                        case NULLS_LAST:
+                            sql.append("LAST");
+                            break;
+                    }
+                }
+                sql.append(", ");
+            }
+
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        return sql;
+    }
+
+    /**
+     * Add a dynamic part of a query for the pagination support.
+     *
+     * @param sql
+     * @param pageable
+     * @return
+     */
+    public static StringBuilder addPaging(StringBuilder sql, Pageable 
pageable) {
+        if (pageable.getSort() != null)
+            addSorting(sql, pageable.getSort());
+
+        sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET 
").append(pageable.getOffset());
+
+        return sql;
+    }
+
+    /**
+     * Determines whether query is dynamic or not (by list of method 
parameters)
+     *
+     * @param mtd
+     * @return type of options
+     */
+    public static IgniteQuery.Option getOptions(Method mtd) {
+        IgniteQuery.Option option;
+
+        Class<?>[] types = mtd.getParameterTypes();
+        Class<?> type = types[types.length - 1];
+
+        if (Sort.class.isAssignableFrom(type))
+            option = IgniteQuery.Option.SORTING;
+        else if (Pageable.class.isAssignableFrom(type))
+            option = IgniteQuery.Option.PAGINATION;
+        else
+            option = IgniteQuery.Option.NONE;
+
+        for (int i = 0; i < types.length - 1; i++) {
+            Class<?> tp = types[i];
+            if (tp == Sort.class || tp == Pageable.class)
+                throw new AssertionError("Sort and Pageable parameters are 
allowed only in the last position");
+        }
+
+        return option;
+    }
+
+    /**
+     * Transform part to sql expression
+     */
+    private static void handleQueryPart(StringBuilder sql, Part part) {
+        sql.append("(");
+
+        sql.append(part.getProperty());
+
+        switch (part.getType()) {
+            case SIMPLE_PROPERTY:
+                sql.append("=?");
+                break;
+            case NEGATING_SIMPLE_PROPERTY:
+                sql.append("<>?");
+                break;
+            case GREATER_THAN:
+                sql.append(">?");
+                break;
+            case GREATER_THAN_EQUAL:
+                sql.append(">=?");
+                break;
+            case LESS_THAN:
+                sql.append("<?");
+                break;
+            case LESS_THAN_EQUAL:
+                sql.append("<=?");
+                break;
+            case IS_NOT_NULL:
+                sql.append(" IS NOT NULL");
+                break;
+            case IS_NULL:
+                sql.append(" IS NULL");
+                break;
+            case BETWEEN:
+                sql.append(" BETWEEN ? AND ?");
+                break;
+            case FALSE:
+                sql.append(" = FALSE");
+                break;
+            case TRUE:
+                sql.append(" = TRUE");
+                break;
+            case CONTAINING:
+                sql.append(" LIKE '%' || ? || '%'");
+                break;
+            case NOT_CONTAINING:
+                sql.append(" NOT LIKE '%' || ? || '%'");
+                break;
+            case LIKE:
+                sql.append(" LIKE '%' || ? || '%'");
+                break;
+            case NOT_LIKE:
+                sql.append(" NOT LIKE '%' || ? || '%'");
+                break;
+            case STARTING_WITH:
+                sql.append(" LIKE  ? || '%'");
+                break;
+            case ENDING_WITH:
+                sql.append(" LIKE '%' || ?");
+                break;
+            case IN:
+                sql.append(" IN ?");
+                break;
+            case NOT_IN:
+                sql.append(" NOT IN ?");
+                break;
+            case REGEX:
+                sql.append(" REGEXP ?");
+                break;
+            case NEAR:
+            case AFTER:
+            case BEFORE:
+            case EXISTS:
+            default:
+                throw new UnsupportedOperationException(part.getType() + " is 
not supported!");
+        }
+
+        sql.append(")");
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
new file mode 100644
index 0000000..c6e171f
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
@@ -0,0 +1,306 @@
+/*
+ * 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.repository.query;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.Query;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.domain.SliceImpl;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.projection.ProjectionFactory;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.QueryMethod;
+import org.springframework.data.repository.query.RepositoryQuery;
+
+/**
+ * Ignite SQL query implementation.
+ */
+@SuppressWarnings("unchecked")
+public class IgniteRepositoryQuery implements RepositoryQuery {
+    /** Defines the way how to process query result */
+    private enum ReturnStrategy {
+        /** Need to return only one value. */
+        ONE_VALUE,
+
+        /** Need to return one cache entry */
+        CACHE_ENTRY,
+
+        /** Need to return list of cache entries */
+        LIST_OF_CACHE_ENTRIES,
+
+        /** Need to return list of values */
+        LIST_OF_VALUES,
+
+        /** Need to return list of lists */
+        LIST_OF_LISTS,
+
+        /** Need to return slice */
+        SLICE_OF_VALUES,
+
+        /** Slice of cache entries. */
+        SLICE_OF_CACHE_ENTRIES,
+
+        /** Slice of lists. */
+        SLICE_OF_LISTS
+    }
+
+    /** Type. */
+    private final Class<?> type;
+    /** Sql. */
+    private final IgniteQuery qry;
+    /** Cache. */
+    private final IgniteCache cache;
+
+    /** Method. */
+    private final Method mtd;
+    /** Metadata. */
+    private final RepositoryMetadata metadata;
+    /** Factory. */
+    private final ProjectionFactory factory;
+
+    /** Return strategy. */
+    private final ReturnStrategy returnStgy;
+
+    /**
+     * @param metadata Metadata.
+     * @param qry Query.
+     * @param mtd Method.
+     * @param factory Factory.
+     * @param cache Cache.
+     */
+    public IgniteRepositoryQuery(RepositoryMetadata metadata, IgniteQuery qry,
+        Method mtd, ProjectionFactory factory, IgniteCache cache) {
+        type = metadata.getDomainType();
+        this.qry = qry;
+        this.cache = cache;
+
+        this.metadata = metadata;
+        this.mtd = mtd;
+        this.factory = factory;
+
+        returnStgy = calcReturnType(mtd, qry.isFieldQuery());
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object execute(Object[] prmtrs) {
+        Query qry = prepareQuery(prmtrs);
+
+        QueryCursor qryCursor = cache.query(qry);
+
+        return transformQueryCursor(prmtrs, qryCursor);
+    }
+
+    /** {@inheritDoc} */
+    @Override public QueryMethod getQueryMethod() {
+        return new QueryMethod(mtd, metadata, factory);
+    }
+
+    /**
+     * @param mtd Method.
+     * @param isFieldQry Is field query.
+     */
+    private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
+        Class<?> returnType = mtd.getReturnType();
+
+        if (returnType.isAssignableFrom(ArrayList.class)) {
+            if (isFieldQry) {
+                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+                    return ReturnStrategy.LIST_OF_LISTS;
+            }
+            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, 
mtd))
+                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
+
+            return ReturnStrategy.LIST_OF_VALUES;
+        }
+        else if (returnType == Slice.class) {
+            if (isFieldQry) {
+                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+                    return ReturnStrategy.SLICE_OF_LISTS;
+            }
+            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, 
mtd))
+                return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
+
+            return ReturnStrategy.SLICE_OF_VALUES;
+        }
+        else if (Cache.Entry.class.isAssignableFrom(returnType))
+            return ReturnStrategy.CACHE_ENTRY;
+        else
+            return ReturnStrategy.ONE_VALUE;
+    }
+
+    /**
+     * @param cls Class 1.
+     * @param mtd Method.
+     */
+    private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method 
mtd) {
+        Type[] actualTypeArguments = 
((ParameterizedType)mtd.getGenericReturnType()).getActualTypeArguments();
+
+        if (actualTypeArguments.length == 0)
+            return false;
+
+        if (actualTypeArguments[0] instanceof ParameterizedType) {
+            ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
+
+            Class<?> type1 = (Class)type.getRawType();
+
+            return type1.isAssignableFrom(cls);
+        }
+
+        if (actualTypeArguments[0] instanceof Class) {
+            Class typeArg = (Class)actualTypeArguments[0];
+
+            return typeArg.isAssignableFrom(cls);
+        }
+
+        return false;
+    }
+
+    /**
+     * @param prmtrs Prmtrs.
+     * @param qryCursor Query cursor.
+     */
+    @Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor 
qryCursor) {
+        if (this.qry.isFieldQuery()) {
+            Iterable<ArrayList> qryIter = (Iterable<ArrayList>)qryCursor;
+
+            switch (returnStgy) {
+                case LIST_OF_VALUES:
+                    ArrayList list = new ArrayList();
+
+                    for (ArrayList entry : qryIter)
+                        list.add(entry.get(0));
+
+                    return list;
+                case ONE_VALUE:
+                    Iterator<ArrayList> iter = qryIter.iterator();
+
+                    if (iter.hasNext())
+                        return iter.next().get(0);
+
+                    return null;
+                case SLICE_OF_VALUES:
+                    ArrayList content = new ArrayList();
+
+                    for (ArrayList entry : qryIter)
+                        content.add(entry.get(0));
+
+                    return new SliceImpl(content, 
(Pageable)prmtrs[prmtrs.length - 1], true);
+                case SLICE_OF_LISTS:
+                    return new SliceImpl(qryCursor.getAll(), 
(Pageable)prmtrs[prmtrs.length - 1], true);
+                case LIST_OF_LISTS:
+                    return qryCursor.getAll();
+                default:
+                    throw new IllegalStateException();
+            }
+        }
+        else {
+            Iterable<CacheEntryImpl> qryIter = 
(Iterable<CacheEntryImpl>)qryCursor;
+
+            switch (returnStgy) {
+                case LIST_OF_VALUES:
+                    ArrayList list = new ArrayList();
+
+                    for (CacheEntryImpl entry : qryIter)
+                        list.add(entry.getValue());
+
+                    return list;
+                case ONE_VALUE:
+                    Iterator<CacheEntryImpl> iter1 = qryIter.iterator();
+
+                    if (iter1.hasNext())
+                        return iter1.next().getValue();
+
+                    return null;
+                case CACHE_ENTRY:
+                    Iterator<CacheEntryImpl> iter2 = qryIter.iterator();
+
+                    if (iter2.hasNext())
+                        return iter2.next();
+
+                    return null;
+                case SLICE_OF_VALUES:
+                    ArrayList content = new ArrayList();
+
+                    for (CacheEntryImpl entry : qryIter)
+                        content.add(entry.getValue());
+
+                    return new SliceImpl(content, 
(Pageable)prmtrs[prmtrs.length - 1], true);
+                case SLICE_OF_CACHE_ENTRIES:
+                    return new SliceImpl(qryCursor.getAll(), 
(Pageable)prmtrs[prmtrs.length - 1], true);
+                case LIST_OF_CACHE_ENTRIES:
+                    return qryCursor.getAll();
+                default:
+                    throw new IllegalStateException();
+            }
+        }
+    }
+
+    /**
+     * @param prmtrs Prmtrs.
+     * @return prepared query for execution
+     */
+    @NotNull private Query prepareQuery(Object[] prmtrs) {
+        Object[] parameters = prmtrs;
+        String sql = qry.sql();
+
+        Query query;
+
+        switch (qry.options()) {
+            case SORTING:
+                sql = IgniteQueryGenerator.addSorting(new StringBuilder(sql),
+                    (Sort)parameters[parameters.length - 1]).toString();
+                parameters = Arrays.copyOfRange(parameters, 0, 
parameters.length - 1);
+                break;
+            case PAGINATION:
+                sql = IgniteQueryGenerator.addPaging(new StringBuilder(sql),
+                    (Pageable)parameters[parameters.length - 1]).toString();
+                parameters = Arrays.copyOfRange(parameters, 0, 
parameters.length - 1);
+                break;
+        }
+
+        if (qry.isFieldQuery()) {
+            SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
+            sqlFieldsQry.setArgs(parameters);
+
+            query = sqlFieldsQry;
+        }
+        else {
+            SqlQuery sqlQry = new SqlQuery(type, sql);
+            sqlQry.setArgs(parameters);
+
+            query = sqlQry;
+        }
+
+        return query;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
new file mode 100644
index 0000000..006bd5a
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
@@ -0,0 +1,176 @@
+/*
+ * 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.repository.support;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.springdata.IgniteKeyValueAdapter;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.query.IgniteQuery;
+import org.apache.ignite.springdata.repository.query.IgniteQueryGenerator;
+import org.apache.ignite.springdata.repository.query.IgniteRepositoryQuery;
+import org.springframework.data.keyvalue.core.KeyValueAdapter;
+import org.springframework.data.keyvalue.core.KeyValueOperations;
+import org.springframework.data.keyvalue.core.KeyValueTemplate;
+import 
org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory;
+import org.springframework.data.projection.ProjectionFactory;
+import org.springframework.data.repository.core.NamedQueries;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.EvaluationContextProvider;
+import org.springframework.data.repository.query.QueryLookupStrategy;
+import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.data.repository.query.parser.AbstractQueryCreator;
+import org.springframework.data.util.ReflectionUtils;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Crucial for spring-data functionality class. Create proxies for 
repositories.
+ */
+public class IgniteRepositoryFactory extends KeyValueRepositoryFactory {
+    /** Ignite instance */
+    private Ignite ignite;
+
+    /** Mapping of a repository to a cache. */
+    private final Map<Class<?>, String> repoToCache = new HashMap<>();
+
+    public IgniteRepositoryFactory(KeyValueOperations keyValueOperations) {
+        super(keyValueOperations);
+
+        initRepositoryFactory(keyValueOperations);
+    }
+
+    public IgniteRepositoryFactory(KeyValueOperations keyValueOperations,
+        Class<? extends AbstractQueryCreator<?, ?>> queryCreator) {
+        super(keyValueOperations, queryCreator);
+
+        initRepositoryFactory(keyValueOperations);
+    }
+
+    public IgniteRepositoryFactory(KeyValueOperations keyValueOperations,
+        Class<? extends AbstractQueryCreator<?, ?>> queryCreator,
+        Class<? extends RepositoryQuery> repositoryQueryType) {
+        super(keyValueOperations, queryCreator, repositoryQueryType);
+
+        initRepositoryFactory(keyValueOperations);
+    }
+
+    private void initRepositoryFactory(KeyValueOperations keyValueOperations) {
+        try {
+            Field field = ReflectionUtils.findField(KeyValueTemplate.class,
+                new org.springframework.util.ReflectionUtils.FieldFilter() {
+                    @Override public boolean matches(Field field) {
+                        return field.getName().equals("adapter");
+                    }
+                });
+
+            field.setAccessible(true);
+
+            IgniteKeyValueAdapter adapter = 
(IgniteKeyValueAdapter)field.get(keyValueOperations);
+
+            field = ReflectionUtils.findField(IgniteKeyValueAdapter.class,
+                new org.springframework.util.ReflectionUtils.FieldFilter() {
+                    @Override public boolean matches(Field field) {
+                        return field.getName().equals("ignite");
+                    }
+                });
+
+            field.setAccessible(true);
+
+            ignite = (Ignite)field.get(adapter);
+
+            if (ignite == null)
+                throw new IgniteException("Failed to initialize 
IgniteRepositoryFactory properly: Ignite instance is " +
+                    "not set in IgniteKeyValueAdapter");
+        }
+        catch (Exception e) {
+            throw new IgniteException("Failed to initialize 
IgniteRepositoryFactory properly.", e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata 
metadata) {
+        return SimpleIgniteRepository.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected RepositoryMetadata getRepositoryMetadata(Class<?> 
repoItf) {
+        Assert.notNull(repoItf, "Repository interface must be set.");
+        Assert.isAssignable(IgniteRepository.class, repoItf, "Repository must 
implement IgniteRepository interface.");
+
+        RepositoryConfig annotation = 
repoItf.getAnnotation(RepositoryConfig.class);
+
+        Assert.notNull(annotation, "Set a name of an Apache Ignite cache using 
@RepositoryConfig annotation to map " +
+            "this repository to the underlying cache.");
+
+        Assert.hasText(annotation.cacheName(), "Set a name of an Apache Ignite 
cache using @RepositoryConfig " +
+            "annotation to map this repository to the underlying cache.");
+
+        repoToCache.put(repoItf, annotation.cacheName());
+
+        return super.getRepositoryMetadata(repoItf);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected QueryLookupStrategy getQueryLookupStrategy(final 
QueryLookupStrategy.Key key,
+        EvaluationContextProvider evaluationCtxProvider) {
+
+        return new QueryLookupStrategy() {
+            @Override public RepositoryQuery resolveQuery(final Method mtd, 
final RepositoryMetadata metadata,
+                final ProjectionFactory factory, NamedQueries namedQueries) {
+
+                final Query annotation = mtd.getAnnotation(Query.class);
+
+                if (annotation != null) {
+                    String qryStr = annotation.value();
+
+                    if (key != Key.CREATE && StringUtils.hasText(qryStr))
+                        return new IgniteRepositoryQuery(metadata,
+                            new IgniteQuery(qryStr, isFieldQuery(qryStr), 
IgniteQueryGenerator.getOptions(mtd)),
+                            mtd, factory, 
ignite.getOrCreateCache(repoToCache.get(metadata.getRepositoryInterface())));
+                }
+
+                if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY)
+                    throw new IllegalStateException("To use 
QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass " +
+                        "a query string via 
org.apache.ignite.springdata.repository.Query annotation.");
+
+                return new IgniteRepositoryQuery(metadata, 
IgniteQueryGenerator.generateSql(mtd, metadata), mtd,
+                    factory, 
ignite.getOrCreateCache(repoToCache.get(metadata.getRepositoryInterface())));
+            }
+        };
+    }
+
+    /**
+     * @param s
+     * @return
+     */
+    private boolean isFieldQuery(String s) {
+        return s.matches("^SELECT.*") && 
!s.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+    }
+}
+
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
new file mode 100644
index 0000000..9d1c8c1
--- /dev/null
+++ 
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
@@ -0,0 +1,55 @@
+/*
+ * 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.repository.support;
+
+import java.io.Serializable;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.springframework.data.keyvalue.core.KeyValueOperations;
+import 
org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory;
+import 
org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean;
+import org.springframework.data.repository.Repository;
+import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.data.repository.query.parser.AbstractQueryCreator;
+
+/**
+ * Apache Ignite repository factory bean.
+ *
+ * @param <T> Repository type, {@link IgniteRepository}
+ * @param <S> Domain object class.
+ * @param <ID> Domain object key, super expects {@link Serializable}.
+ */
+public class IgniteRepositoryFactoryBean<T extends Repository<S, ID>, S, ID 
extends Serializable>
+    extends KeyValueRepositoryFactoryBean<T, S, ID> {
+
+    /**
+     * Creates a new {@code IgniteRepositoryFactoryBean} for the given 
repository interface.
+     *
+     * @param repositoryInterface must not be {@literal null}.
+     */
+    public IgniteRepositoryFactoryBean(Class<? extends T> repositoryInterface) 
{
+        super(repositoryInterface);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected KeyValueRepositoryFactory 
createRepositoryFactory(KeyValueOperations operations,
+        Class<? extends AbstractQueryCreator<?, ?>> queryCreator,
+        Class<? extends RepositoryQuery> repositoryQueryType) {
+        return new IgniteRepositoryFactory(operations, queryCreator, 
repositoryQueryType);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataSelfTest.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataSelfTest.java
new file mode 100644
index 0000000..a097c29
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataSelfTest.java
@@ -0,0 +1,286 @@
+/*
+ * 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.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.misc.FirstRepository;
+import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.SecondRepository;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.domain.Sort;
+
+/**
+ *
+ */
+public class IgniteSpringDataSelfTest extends GridCommonAbstractTest {
+    /** Repository. */
+    private static FirstRepository repo;
+
+    /** Repository 2. */
+    private static SecondRepository repo2;
+
+    /** Context. */
+    private static AnnotationConfigApplicationContext ctx;
+
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        ctx = new AnnotationConfigApplicationContext();
+
+        ctx.scan("org.apache.ignite.springdata");
+        ctx.refresh();
+
+        repo = ctx.getBean(FirstRepository.class);
+        repo2 = ctx.getBean(SecondRepository.class);
+
+        for (int i = 0; i < 1000; i++)
+            repo.save(i, new Person("person" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+    }
+
+    @Override protected void afterTestsStopped() throws Exception {
+        ctx.destroy();
+
+        super.afterTestsStopped();
+    }
+
+    /** */
+    public void testExplicitQuery() {
+        List<Person> persons = repo.simpleQuery("person4a");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4a", person.getFirstName());
+    }
+
+    /** */
+    public void testEqualsPart() {
+        List<Person> persons = repo.findByFirstName("person4e");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4e", person.getFirstName());
+    }
+
+    /** */
+    public void testContainingPart() {
+        List<Person> persons = repo.findByFirstNameContaining("person4");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertTrue(person.getFirstName().startsWith("person4"));
+    }
+
+    /** */
+    public void testTopPart() {
+        Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
+
+        Iterator<Person> iter = top.iterator();
+
+        Person person = iter.next();
+
+        assertFalse(iter.hasNext());
+
+        assertTrue(person.getFirstName().startsWith("person4"));
+    }
+
+    /** */
+    public void testLikeAndLimit() {
+        Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
+
+        int cnt = 0;
+
+        for (Person next : like) {
+            assertTrue(next.getFirstName().contains("person"));
+
+            cnt++;
+        }
+
+        assertEquals(10, cnt);
+    }
+
+    /** */
+    public void testCount() {
+        int cnt = repo.countByFirstNameLike("person");
+
+        assertEquals(1000, cnt);
+    }
+
+    /** */
+    public void testCount2() {
+        int cnt = repo.countByFirstNameLike("person4");
+
+        assertTrue(cnt < 1000);
+    }
+
+    /** */
+    public void testPageable() {
+        PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, 
"firstName");
+
+        HashSet<String> firstNames = new HashSet<>();
+
+        List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", 
pageable);
+
+        assertEquals(5, pageable1.size());
+
+        for (Person person : pageable1) {
+            firstNames.add(person.getFirstName());
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+        }
+
+        List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", 
pageable.next());
+
+        assertEquals(5, pageable2.size());
+
+        for (Person person : pageable2) {
+            firstNames.add(person.getFirstName());
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+        }
+
+        assertEquals(10, firstNames.size());
+    }
+
+    /** */
+    public void testAndAndOr() {
+        int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", 
"lastName1");
+
+        int cntOr = 
repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", 
"lastName1");
+
+        assertTrue(cntAnd <= cntOr);
+    }
+
+    /** */
+    public void testQueryWithSort() {
+        List<Person> persons = repo.queryWithSort("^[a-z]+$", new 
Sort(Sort.Direction.DESC, "secondName"));
+
+        Person previous = persons.get(0);
+
+        for (Person person : persons) {
+            
assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
+
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+
+            previous = person;
+        }
+    }
+
+    /** */
+    public void testQueryWithPaging() {
+        List<Person> persons = repo.queryWithPageable("^[a-z]+$", new 
PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+
+        assertEquals(7, persons.size());
+
+        Person previous = persons.get(0);
+
+        for (Person person : persons) {
+            
assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
+
+            assertTrue(person.getFirstName().matches("^[a-z]+$"));
+
+            previous = person;
+        }
+    }
+
+    /** */
+    public void testQueryFields() {
+        List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 
7, Sort.Direction.DESC, "secondName"));
+
+        assertEquals(7, persons.size());
+    }
+
+    /** */
+    public void testFindCacheEntries() {
+        List<Cache.Entry<Integer, Person>> cacheEntries = 
repo.findBySecondNameLike("stName1");
+
+        assertFalse(cacheEntries.isEmpty());
+
+        for (Cache.Entry<Integer, Person> entry : cacheEntries)
+            assertTrue(entry.getValue().getSecondName().contains("stName1"));
+    }
+
+    /** */
+    public void testFindOneCacheEntry() {
+        Cache.Entry<Integer, Person> cacheEntry = 
repo.findTopBySecondNameLike("tName18");
+
+        assertNotNull(cacheEntry);
+
+        assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
+    }
+
+    /** */
+    public void testFindOneValue() {
+        Person person = repo.findTopBySecondNameStartingWith("lastName18");
+
+        assertNotNull(person);
+
+        assertTrue(person.getSecondName().startsWith("lastName18"));
+    }
+
+    /** */
+    public void testSelectSeveralFields() {
+        List<List> lists = repo.selectSeveralField("^[a-z]+$", new 
PageRequest(2, 6));
+
+        assertEquals(6, lists.size());
+
+        for (List list : lists) {
+            assertEquals(2, list.size());
+
+            assertTrue(list.get(0) instanceof Integer);
+        }
+    }
+
+    /** */
+    public void testCountQuery() {
+        int cnt = repo.countQuery(".*");
+
+        assertEquals(256, cnt);
+    }
+
+    /** */
+    public void testSliceOfCacheEntries() {
+        Slice<Cache.Entry<Integer, Person>> slice = 
repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
+
+        assertEquals(4, slice.getSize());
+
+        for (Cache.Entry<Integer, Person> entry : slice)
+            assertFalse("lastName18".equals(entry.getValue().getSecondName()));
+    }
+
+    /** */
+    public void testSliceOfLists() {
+        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new 
PageRequest(0, 3));
+
+        assertEquals(3, lists.getSize());
+
+        for (List list : lists) {
+            assertEquals(2, list.size());
+
+            assertTrue(list.get(0) instanceof Integer);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataTestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataTestSuite.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataTestSuite.java
new file mode 100644
index 0000000..fb8c2a4
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataTestSuite.java
@@ -0,0 +1,38 @@
+/*
+ * 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 junit.framework.TestSuite;
+
+/**
+ *
+ */
+public class IgniteSpringDataTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Spring Data Test Suite");
+
+        suite.addTest(new IgniteSpringDataSelfTest());
+
+        return suite;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
new file mode 100644
index 0000000..aa7a7ae
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
@@ -0,0 +1,59 @@
+/*
+ * 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.misc;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.springdata.IgniteKeyValueAdapter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.springframework.data.keyvalue.core.KeyValueOperations;
+import org.springframework.data.keyvalue.core.KeyValueTemplate;
+
+/**
+ *
+ */
+@Configuration
+@EnableIgniteRepositories
+public class ApplicationConfiguration {
+    @Bean
+    public Ignite igniteInstance() {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        CacheConfiguration ccfg = new CacheConfiguration("cache");
+
+        ccfg.setIndexedTypes(Integer.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return Ignition.start(cfg);
+    }
+
+    @Bean
+    public KeyValueOperations igniteKeyValueTemplate(Ignite igniteInstance) {
+        return new KeyValueTemplate(new IgniteKeyValueAdapter(igniteInstance));
+    }
+
+    @Bean
+    public IgniteKeyValueAdapter igniteKeyValueAdapter(Ignite igniteInstance) {
+        return new IgniteKeyValueAdapter(igniteInstance);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/FirstRepository.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/FirstRepository.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/FirstRepository.java
new file mode 100644
index 0000000..315162d
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/FirstRepository.java
@@ -0,0 +1,92 @@
+
+/*
+ * 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.misc;
+
+import java.util.Collection;
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.repository.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+
+/**
+ *
+ */
+@RepositoryConfig(cacheName = "cache")
+public interface FirstRepository extends IgniteRepository<Person, Integer> {
+    /** */
+    public List<Person> findByFirstName(String val);
+
+    /** */
+    public List<Person> findByFirstNameContaining(String val);
+
+    /** */
+    public List<Person> findByFirstNameRegex(String val, Pageable pageable);
+
+    /** */
+    public Collection<Person> findTopByFirstNameContaining(String val);
+
+    /** */
+    public Iterable<Person> findFirst10ByFirstNameLike(String val);
+
+    /** */
+    public int countByFirstNameLike(String val);
+
+    /** */
+    public int countByFirstNameLikeAndSecondNameLike(String like1, String 
like2);
+
+    /** */
+    public int countByFirstNameStartingWithOrSecondNameStartingWith(String 
like1, String like2);
+
+    /** */
+    public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
+
+    /** */
+    public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
+
+    /** */
+    public Person findTopBySecondNameStartingWith(String val);
+
+    /** */
+    @Query("firstName = ?")
+    public List<Person> simpleQuery(String val);
+
+    /** */
+    @Query("firstName REGEXP ?")
+    public List<Person> queryWithSort(String val, Sort sort);
+
+    /** */
+    @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
+    public List<Person> queryWithPageable(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
+    public List<String> selectField(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
+    public List<List> selectSeveralField(String val, Pageable pageable);
+
+    /** */
+    @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE 
firstName REGEXP ?)")
+    public int countQuery(String val);
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
new file mode 100644
index 0000000..502d86d
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
@@ -0,0 +1,75 @@
+/*
+ * 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.misc;
+
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+
+public class Person {
+    /** First name. */
+    @QuerySqlField(index = true)
+    private String firstName;
+
+    /** Second name. */
+    @QuerySqlField(index = true)
+    private String secondName;
+
+    /**
+     * @param firstName First name.
+     * @param secondName Second name.
+     */
+    public Person(String firstName, String secondName) {
+        this.firstName = firstName;
+        this.secondName = secondName;
+    }
+
+    /**
+     *
+     */
+    public String getFirstName() {
+        return firstName;
+    }
+
+    /**
+     * @param firstName First name.
+     */
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    /**
+     *
+     */
+    public String getSecondName() {
+        return secondName;
+    }
+
+    /**
+     * @param secondName Second name.
+     */
+    public void setSecondName(String secondName) {
+        this.secondName = secondName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Person{" +
+            "firstName='" + firstName + '\'' +
+            ", secondName='" + secondName + '\'' +
+            '}';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/SecondRepository.java
----------------------------------------------------------------------
diff --git 
a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/SecondRepository.java
 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/SecondRepository.java
new file mode 100644
index 0000000..63b0b8f
--- /dev/null
+++ 
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/SecondRepository.java
@@ -0,0 +1,40 @@
+/*
+ * 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.misc;
+
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.AbstractPageRequest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+
+/**
+ *
+ */
+@RepositoryConfig(cacheName = "cache")
+public interface SecondRepository extends IgniteRepository<Person, Integer> {
+    /** */
+    public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String 
val, PageRequest pageReq);
+
+    /** */
+    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
+    public Slice<List> querySliceOfList(String val, AbstractPageRequest 
pageReq);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-console/README.txt b/modules/web-console/README.txt
index 286082c..77c3ec4 100644
--- a/modules/web-console/README.txt
+++ b/modules/web-console/README.txt
@@ -16,7 +16,7 @@ In order to simplify evaluation of Web Console demo mode was 
implemented.
     2) Click "Import from database". You should see modal with demo 
description.
     3) Click "Next" button. You should see list of available schemas.
     4) Click "Next" button. You should see list of available tables.
-    5) Click "Next" button. You should see import options.
+    5) Click "Next" button. You should see import option.
     6) Select some of them and click "Save".
 
  Demo for SQL.

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
 
b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
index 9b14fca..f1c0ae7 100644
--- 
a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
+++ 
b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.tpl.pug
@@ -20,7 +20,7 @@
             .ui-grid-header-canvas
                 
.ui-grid-header-cell-wrapper(ng-style='colContainer.headerCellWrapperStyle()')
                     .ui-grid-header-cell-row(role='row')
-                        
.ui-grid-header-span.ui-grid-header-cell.ui-grid-clearfix.ui-grid-category(ng-repeat='cat
 in grid.options.categories', ng-if='cat.visible && \
+                        
.ui-grid-header-span.ui-grid-header-cell.ui-grid-clearfix.ui-grid-category(ng-repeat='cat
 in grid.option.categories', ng-if='cat.visible && \
                         (colContainer.renderedColumns | uiGridSubcategories: 
cat.name).length > 0')
                             
div(ng-show='(colContainer.renderedColumns|uiGridSubcategories:cat.name).length 
> 1')
                                 .ui-grid-cell-contents {{ cat.name }}

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.pug 
b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.pug
index 4bee5e5..2eb222c 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.pug
+++ b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.pug
@@ -22,7 +22,7 @@ mixin check-tooltip(message)
         .col-xs-2.col-sm-2.col-md-2
             label POJO class:
         .col-xs-10.col-sm-10.col-md-10.summary-pojo-list
-            button.select-toggle.form-control(ng-model='ctrl.class' bs-select 
bs-options='item for item in ctrl.classes' data-container='')
+            button.select-toggle.form-control(ng-model='ctrl.class' bs-select 
bs-option='item for item in ctrl.classes' data-container='')
     .details-row.checkbox
         .col-xs-2.col-sm-2.col-md-2
         .col-xs-10.col-sm-10.col-md-10

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.pug 
b/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.pug
index fe7f912..61d3dd0 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.pug
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.pug
@@ -16,14 +16,14 @@
 
 mixin form-field-checkbox(label, model, name, disabled, required, tip)
     //- TODO: Need to use common tooltip.
-    mixin tooltip-checkbox(title, options)
+    mixin tooltip-checkbox(title, option)
         if title
             i.tipLabel.icon-help(
                 bs-tooltip=''
 
                 data-title=title
-                data-container=options && options.container || false
-                data-placement=options && options.placement || false
+                data-container=option && option.container || false
+                data-placement=option && option.placement || false
             )
 
     div.checkbox.col-xs-12.col-sm-12.col-md-12

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.pug 
b/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.pug
index 6da1255..f8597ca 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.pug
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.pug
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin form-field-datalist(label, model, name, disabled, required, placeholder, 
options, tip)
+mixin form-field-datalist(label, model, name, disabled, required, placeholder, 
option, tip)
     -var errLbl = label.substring(0, label.length - 1)
 
     mixin form-field-input()
@@ -26,10 +26,10 @@ mixin form-field-datalist(label, model, name, disabled, 
required, placeholder, o
             data-ng-model=model
 
             data-ng-required=required && `${required}`
-            data-ng-disabled=disabled && `${disabled}` || `!${options}.length`
+            data-ng-disabled=disabled && `${disabled}` || `!${option}.length`
 
             bs-typeahead
-            bs-options=`item for item in ${options}`
+            bs-option=`item for item in ${option}`
             container='body'
             data-min-length='1'
             ignite-retain-selection

http://git-wip-us.apache.org/repos/asf/ignite/blob/362700c6/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.pug
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.pug 
b/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.pug
index 2f13d69..23fca2e 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.pug
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.pug
@@ -14,21 +14,21 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-mixin ignite-form-field-dropdown(label, model, name, disabled, required, 
multiple, placeholder, placeholderEmpty, options, tip)
+mixin ignite-form-field-dropdown(label, model, name, disabled, required, 
multiple, placeholder, placeholderEmpty, option, tip)
     mixin form-field-input()
         button.select-toggle.form-control(
             id=`{{ ${name} }}Input`
             name=`{{ ${name} }}`
 
-            data-placeholder=placeholderEmpty ? `{{ ${options}.length > 0 ? 
'${placeholder}' : '${placeholderEmpty}' }}` : placeholder
+            data-placeholder=placeholderEmpty ? `{{ ${option}.length > 0 ? 
'${placeholder}' : '${placeholderEmpty}' }}` : placeholder
             
             data-ng-model=model
 
             data-ng-required=required && `${required}`
-            data-ng-disabled=disabled && `${disabled}` || `!${options}.length`
+            data-ng-disabled=disabled && `${disabled}` || `!${option}.length`
 
             bs-select
-            bs-options=`item.value as item.label for item in ${options}`
+            bs-option=`item.value as item.label for item in ${option}`
 
             data-multiple=multiple ? '1' : false
             data-container='body > .wrapper'

Reply via email to