You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by na...@apache.org on 2021/05/26 16:02:24 UTC
[ignite-extensions] branch master updated: IGNITE-14767 Add
examples to spring-data-2.2 module. (#62)
This is an automated email from the ASF dual-hosted git repository.
namelchev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-extensions.git
The following commit(s) were added to refs/heads/master by this push:
new 83a4612 IGNITE-14767 Add examples to spring-data-2.2 module. (#62)
83a4612 is described below
commit 83a4612bd56351596f827b14cc77023053bf5804
Author: Mikhail Petrov <32...@users.noreply.github.com>
AuthorDate: Wed May 26 19:02:14 2021 +0300
IGNITE-14767 Add examples to spring-data-2.2 module. (#62)
---
.../examples/config/example-default.xml | 76 +++++++++
.../examples/config/example-spring-data.xml | 64 ++++++++
...IgniteClientSpringApplicationConfiguration.java | 53 ++++++
.../springdata22/examples/PersonRepository.java | 59 +++++++
.../examples/SpringApplicationConfiguration.java | 51 ++++++
.../springdata22/examples/SpringDataExample.java | 181 +++++++++++++++++++++
.../springdata22/examples/model/Address.java | 72 ++++++++
.../springdata22/examples/model/Employee.java | 93 +++++++++++
.../springdata22/examples/model/EmployeeKey.java | 93 +++++++++++
.../springdata22/examples/model/Organization.java | 132 +++++++++++++++
.../examples/model/OrganizationType.java | 32 ++++
.../ignite/springdata22/examples/model/Person.java | 145 +++++++++++++++++
modules/spring-data-2.2-ext/pom.xml | 53 ++++++
13 files changed, 1104 insertions(+)
diff --git a/modules/spring-data-2.2-ext/examples/config/example-default.xml b/modules/spring-data-2.2-ext/examples/config/example-default.xml
new file mode 100644
index 0000000..e6c359d
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/config/example-default.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite configuration with all defaults and enabled p2p deployment and enabled events.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <bean abstract="true" id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <!-- Set to true to enable distributed class loading for examples, default is false. -->
+ <property name="peerClassLoadingEnabled" value="true"/>
+
+ <!-- Enable task execution events for examples. -->
+ <property name="includeEventTypes">
+ <list>
+ <!--Task execution events-->
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/>
+
+ <!--Cache events-->
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/>
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/>
+ </list>
+ </property>
+
+ <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+ <property name="discoverySpi">
+ <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
+ to our documentation: http://apacheignite.readme.io/docs/cluster-config
+ -->
+ <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
+ <!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with actual host IP address. -->
+ <value>127.0.0.1:47500..47509</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml b/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
new file mode 100644
index 0000000..9f7d674
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup Ignite cache.
+
+ This file demonstrates how to configure cache using Spring. Provided cache
+ will be created on node startup.
+
+ Use this configuration file when running Spring Data examples.
+
+ When starting a standalone node, you need to execute the following command:
+ {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-2.2/examples/config/example-spring-data.xml
+
+ When starting Ignite from Java IDE, pass path to this file to Ignition:
+ Ignition.start("modules/spring-data-2.2/examples/config/example-spring-data.xml");
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+ <!-- Imports default Ignite configuration -->
+ <import resource="example-default.xml"/>
+
+ <bean parent="ignite.cfg">
+ <property name="igniteInstanceName" value="springDataNode" />
+
+ <property name="cacheConfiguration">
+ <list>
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <!--
+ Apache Ignite uses an IgniteRepository extension which inherits from Spring Data's CrudRepository.
+ The SQL grid is also enabled to aceess Spring Data repository. The @RepositoryConfig annotation
+ maps the PersonRepository to an Ignite's cache named "PersonCache".
+ -->
+ <property name="name" value="PersonCache"/>
+ <property name="indexedTypes">
+ <list>
+ <value>java.lang.Long</value>
+ <value>org.apache.ignite.springdata22.examples.model.Person</value>
+ </list>
+ </property>
+ </bean>
+ </list>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
new file mode 100644
index 0000000..72d8eaa
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * 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.springdata22.examples;
+
+import org.apache.ignite.Ignition;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.apache.ignite.configuration.ClientConnectorConfiguration.DFLT_PORT;
+
+/**
+ * Example of Spring application configuration that represents beans required to configure Spring Data repository access
+ * to an Ignite cluster through the thin client.
+ *
+ * Note that both Ignite thin client and Ignite node approaches of Ignite cluster access configuration uses the same API.
+ * Ignite Spring Data integration automatically recognizes the type of provided bean and use the appropriate
+ * cluster connection.
+ *
+ * @see SpringApplicationConfiguration
+ */
+@Configuration
+@EnableIgniteRepositories
+public class IgniteClientSpringApplicationConfiguration {
+ /**
+ * Creates Apache Ignite thin client instance bean which will be used for accessing the Ignite cluster.
+ * Note, that the name of the current bean must match value of {@link RepositoryConfig#igniteInstance}
+ * property that {@link PersonRepository} is marked with. In this particular case, the default value of
+ * {@link RepositoryConfig#igniteInstance} property is used.
+ */
+ @Bean
+ public IgniteClient igniteInstance() {
+ return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + DFLT_PORT));
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java
new file mode 100644
index 0000000..24b8bdb
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/PersonRepository.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.springdata22.examples;
+
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.springdata22.examples.model.Person;
+import org.apache.ignite.springdata22.repository.IgniteRepository;
+import org.apache.ignite.springdata22.repository.config.Query;
+import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.springframework.data.domain.Pageable;
+
+/**
+ * Apache Ignite Spring Data repository backed by Ignite Person's cache.
+ * </p>
+ * To link the repository with an Ignite cache use {@link RepositoryConfig#cacheName()} annotation's parameter.
+ */
+@RepositoryConfig(cacheName = "PersonCache")
+public interface PersonRepository extends IgniteRepository<Person, Long> {
+ /**
+ * Gets all the persons with the given name.
+ * @param name Person name.
+ * @return A list of Persons with the given first name.
+ */
+ public List<Person> findByFirstName(String name);
+
+ /**
+ * Returns top Person with the specified surname.
+ * @param name Person surname.
+ * @return Person that satisfy the query.
+ */
+ public Cache.Entry<Long, Person> findTopByLastNameLike(String name);
+
+ /**
+ * Getting ids of all the Person satisfying the custom query from {@link Query} annotation.
+ *
+ * @param orgId Query parameter.
+ * @param pageable Pageable interface.
+ * @return A list of Persons' ids.
+ */
+ @Query("SELECT id FROM Person WHERE orgId > ?")
+ public List<Long> selectId(long orgId, Pageable pageable);
+}
+
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
new file mode 100644
index 0000000..d3ca61e
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
@@ -0,0 +1,51 @@
+/*
+ * 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.springdata22.examples;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.springdata22.repository.IgniteRepository;
+import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Every {@link IgniteRepository} is bound to a specific Apache Ignite that it communicates to in order to mutate and
+ * read data via Spring Data API. To pass an instance of Apache Ignite cache to an {@link IgniteRepository} it's
+ * required to initialize {@link IgniteRepositoryFactoryBean} with one of the following:
+ * <ul>
+ * <li>{@link Ignite} instance bean</li>
+ * <li>{@link IgniteConfiguration} bean</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <ul/>
+ * In this example the first approach is utilized.
+ */
+@Configuration
+@EnableIgniteRepositories
+public class SpringApplicationConfiguration {
+ /**
+ * Creating Apache Ignite instance bean. A bean will be passed to {@link IgniteRepositoryFactoryBean} to initialize
+ * all Ignite based Spring Data repositories and connect to a cluster.
+ */
+ @Bean
+ public Ignite igniteInstance() {
+ return Ignition.start("modules/spring-data-2.2-ext/examples/config/example-spring-data.xml");
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
new file mode 100644
index 0000000..f585673
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
@@ -0,0 +1,181 @@
+/*
+ * 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.springdata22.examples;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+import javax.cache.Cache;
+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.springdata22.examples.model.Person;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.data.domain.PageRequest;
+
+/**
+ * The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
+ *
+ * Additional cluster nodes can be started with special configuration file which
+ * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data-2.2/examples/config/example-spring-data.xml'}.
+ */
+public class SpringDataExample {
+ /** Spring Application Context. */
+ private static AnnotationConfigApplicationContext ctx;
+
+ /** Ignite Spring Data repository. */
+ private static PersonRepository repo;
+
+ /**
+ * Execute examples involving both approaches to configure Spring Data repository access to an Ignite cluster:
+ * through Ignite thin client and through Ignite node.
+ * @param args Command line arguments, none required.
+ */
+ public static void main(String[] args) {
+ try (Ignite ignored = startIgniteNode()) {
+ // Ignite node instance is used to configure access to the Ignite cluster.
+ doSpringDataExample(SpringApplicationConfiguration.class);
+
+ // Ignite thin client instance is used to configure access to the Ignite cluster.
+ doSpringDataExample(IgniteClientSpringApplicationConfiguration.class);
+ }
+ }
+
+ /** Starts an Ignite node that simulates an Ignite cluster to which Spring Data repository will perform access. */
+ private static Ignite startIgniteNode() {
+ IgniteConfiguration cfg = new IgniteConfiguration()
+ .setPeerClassLoadingEnabled(true)
+ .setCacheConfiguration(new CacheConfiguration<Long, Person>("PersonCache")
+ .setIndexedTypes(Long.class, Person.class));
+
+ return Ignition.start(cfg);
+ }
+
+ /**
+ * Performs basic Spring Data repository operation.
+ *
+ * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
+ */
+ private static void doSpringDataExample(Class<?> springAppCfg) {
+ igniteSpringDataInit(springAppCfg);
+
+ populateRepository();
+
+ findPersons();
+
+ queryRepository();
+
+ System.out.println("\n>>> Cleaning out the repository...");
+
+ repo.deleteAll();
+
+ System.out.println("\n>>> Repository size: " + repo.count());
+
+ // Destroying the context.
+ ctx.destroy();
+ }
+
+ /**
+ * Initializes Spring Data and Ignite repositories.
+ *
+ * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
+ */
+ private static void igniteSpringDataInit(Class<?> springAppCfg) {
+ ctx = new AnnotationConfigApplicationContext();
+
+ // Explicitly registering Spring configuration.
+ ctx.register(springAppCfg);
+
+ ctx.refresh();
+
+ // Getting a reference to PersonRepository.
+ repo = ctx.getBean(PersonRepository.class);
+ }
+
+ /**
+ * Fills the repository in with sample data.
+ */
+ private static void populateRepository() {
+ TreeMap<Long, Person> persons = new TreeMap<>();
+
+ persons.put(1L, new Person(1L, 2000L, "John", "Smith", 15000, "Worked for Apple"));
+ persons.put(2L, new Person(2L, 2000L, "Brad", "Pitt", 16000, "Worked for Oracle"));
+ persons.put(3L, new Person(3L, 1000L, "Mark", "Tomson", 10000, "Worked for Sun"));
+ persons.put(4L, new Person(4L, 2000L, "Erick", "Smith", 13000, "Worked for Apple"));
+ persons.put(5L, new Person(5L, 1000L, "John", "Rozenberg", 25000, "Worked for RedHat"));
+ persons.put(6L, new Person(6L, 2000L, "Denis", "Won", 35000, "Worked for CBS"));
+ persons.put(7L, new Person(7L, 1000L, "Abdula", "Adis", 45000, "Worked for NBC"));
+ persons.put(8L, new Person(8L, 2000L, "Roman", "Ive", 15000, "Worked for Sun"));
+
+ // Adding data into the repository.
+ repo.save(persons);
+
+ System.out.println("\n>>> Added " + repo.count() + " Persons into the repository.");
+ }
+
+ /**
+ * Gets a list of Persons using standard read operations.
+ */
+ private static void findPersons() {
+ // Getting Person with specific ID.
+ Person person = repo.findById(2L).orElse(null);
+
+ System.out.println("\n>>> Found Person [id=" + 2L + ", val=" + person + "]");
+
+ // Getting a list of Persons.
+
+ ArrayList<Long> ids = new ArrayList<>();
+
+ for (long i = 0; i < 5; i++)
+ ids.add(i);
+
+ Iterator<Person> persons = repo.findAllById(ids).iterator();
+
+ System.out.println("\n>>> Persons list for specific ids: ");
+
+ while (persons.hasNext())
+ System.out.println(" >>> " + persons.next());
+ }
+
+ /**
+ * Execute advanced queries over the repository.
+ */
+ private static void queryRepository() {
+ System.out.println("\n>>> Persons with name 'John':");
+
+ List<Person> persons = repo.findByFirstName("John");
+
+ for (Person person: persons)
+ System.out.println(" >>> " + person);
+
+
+ Cache.Entry<Long, Person> topPerson = repo.findTopByLastNameLike("Smith");
+
+ System.out.println("\n>>> Top Person with surname 'Smith': " + topPerson.getValue());
+
+
+ List<Long> ids = repo.selectId(1000L, PageRequest.of(0, 4));
+
+ System.out.println("\n>>> Persons working for organization with ID > 1000: ");
+
+ for (Long id: ids)
+ System.out.println(" >>> [id=" + id + "]");
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Address.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Address.java
new file mode 100644
index 0000000..6e00981
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Address.java
@@ -0,0 +1,72 @@
+/*
+ * 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.springdata22.examples.model;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryReader;
+import org.apache.ignite.binary.BinaryWriter;
+import org.apache.ignite.binary.Binarylizable;
+
+/**
+ * Employee address.
+ * <p>
+ * This class implements {@link Binarylizable} only for example purposes,
+ * in order to show how to customize serialization and deserialization of
+ * binary objects.
+ */
+public class Address implements Binarylizable {
+ /** Street. */
+ private String street;
+
+ /** ZIP code. */
+ private int zip;
+
+ /**
+ * Required for binary deserialization.
+ */
+ public Address() {
+ // No-op.
+ }
+
+ /**
+ * @param street Street.
+ * @param zip ZIP code.
+ */
+ public Address(String street, int zip) {
+ this.street = street;
+ this.zip = zip;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
+ writer.writeString("street", street);
+ writer.writeInt("zip", zip);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
+ street = reader.readString("street");
+ zip = reader.readInt("zip");
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Address [street=" + street +
+ ", zip=" + zip + ']';
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Employee.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
new file mode 100644
index 0000000..12a99fa
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
@@ -0,0 +1,93 @@
+/*
+ * 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.springdata22.examples.model;
+
+import java.util.Collection;
+
+/**
+ * This class represents employee object.
+ */
+public class Employee {
+ /** Name. */
+ private String name;
+
+ /** Salary. */
+ private long salary;
+
+ /** Address. */
+ private Address addr;
+
+ /** Departments. */
+ private Collection<String> departments;
+
+ /**
+ * Required for binary deserialization.
+ */
+ public Employee() {
+ // No-op.
+ }
+
+ /**
+ * @param name Name.
+ * @param salary Salary.
+ * @param addr Address.
+ * @param departments Departments.
+ */
+ public Employee(String name, long salary,Address addr, Collection<String> departments) {
+ this.name = name;
+ this.salary = salary;
+ this.addr = addr;
+ this.departments = departments;
+ }
+
+ /**
+ * @return Name.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * @return Salary.
+ */
+ public long salary() {
+ return salary;
+ }
+
+ /**
+ * @return Address.
+ */
+ public Address address() {
+ return addr;
+ }
+
+ /**
+ * @return Departments.
+ */
+ public Collection<String> departments() {
+ return departments;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Employee [name=" + name +
+ ", salary=" + salary +
+ ", address=" + addr +
+ ", departments=" + departments + ']';
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
new file mode 100644
index 0000000..2127eaf
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
@@ -0,0 +1,93 @@
+/*
+ * 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.springdata22.examples.model;
+
+import org.apache.ignite.cache.affinity.AffinityKeyMapped;
+
+/**
+ * This class represents key for employee object.
+ * <p>
+ * Used in query example to collocate employees
+ * with their organizations.
+ */
+public class EmployeeKey {
+ /** ID. */
+ private int id;
+
+ /** Organization ID. */
+ @AffinityKeyMapped
+ private int organizationId;
+
+ /**
+ * Required for binary deserialization.
+ */
+ public EmployeeKey() {
+ // No-op.
+ }
+
+ /**
+ * @param id ID.
+ * @param organizationId Organization ID.
+ */
+ public EmployeeKey(int id, int organizationId) {
+ this.id = id;
+ this.organizationId = organizationId;
+ }
+
+ /**
+ * @return ID.
+ */
+ public int id() {
+ return id;
+ }
+
+ /**
+ * @return Organization ID.
+ */
+ public int organizationId() {
+ return organizationId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ EmployeeKey key = (EmployeeKey)o;
+
+ return id == key.id && organizationId == key.organizationId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = id;
+
+ res = 31 * res + organizationId;
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "EmployeeKey [id=" + id +
+ ", organizationId=" + organizationId + ']';
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Organization.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
new file mode 100644
index 0000000..a6ba676
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
@@ -0,0 +1,132 @@
+/*
+ * 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.springdata22.examples.model;
+
+import java.sql.Timestamp;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+
+/**
+ * This class represents organization object.
+ */
+public class Organization {
+ /** */
+ private static final AtomicLong ID_GEN = new AtomicLong();
+
+ /** Organization ID (indexed). */
+ @QuerySqlField(index = true)
+ private Long id;
+
+ /** Organization name (indexed). */
+ @QuerySqlField(index = true)
+ private String name;
+
+ /** Address. */
+ private Address addr;
+
+ /** Type. */
+ private OrganizationType type;
+
+ /** Last update time. */
+ private Timestamp lastUpdated;
+
+ /**
+ * Required for binary deserialization.
+ */
+ public Organization() {
+ // No-op.
+ }
+
+ /**
+ * @param name Organization name.
+ */
+ public Organization(String name) {
+ id = ID_GEN.incrementAndGet();
+
+ this.name = name;
+ }
+
+ /**
+ * @param id Organization ID.
+ * @param name Organization name.
+ */
+ public Organization(long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ /**
+ * @param name Name.
+ * @param addr Address.
+ * @param type Type.
+ * @param lastUpdated Last update time.
+ */
+ public Organization(String name, Address addr, OrganizationType type, Timestamp lastUpdated) {
+ id = ID_GEN.incrementAndGet();
+
+ this.name = name;
+ this.addr = addr;
+ this.type = type;
+
+ this.lastUpdated = lastUpdated;
+ }
+
+ /**
+ * @return Organization ID.
+ */
+ public Long id() {
+ return id;
+ }
+
+ /**
+ * @return Name.
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * @return Address.
+ */
+ public Address address() {
+ return addr;
+ }
+
+ /**
+ * @return Type.
+ */
+ public OrganizationType type() {
+ return type;
+ }
+
+ /**
+ * @return Last update time.
+ */
+ public Timestamp lastUpdated() {
+ return lastUpdated;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Organization [id=" + id +
+ ", name=" + name +
+ ", address=" + addr +
+ ", type=" + type +
+ ", lastUpdated=" + lastUpdated + ']';
+ }
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
new file mode 100644
index 0000000..140ff4e
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
@@ -0,0 +1,32 @@
+/*
+ * 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.springdata22.examples.model;
+
+/**
+ * Organization type enum.
+ */
+public enum OrganizationType {
+ /** Non-profit organization. */
+ NON_PROFIT,
+
+ /** Private organization. */
+ PRIVATE,
+
+ /** Government organization. */
+ GOVERNMENT
+}
diff --git a/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Person.java b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Person.java
new file mode 100644
index 0000000..585c458
--- /dev/null
+++ b/modules/spring-data-2.2-ext/examples/main/java/org/apache/ignite/springdata22/examples/model/Person.java
@@ -0,0 +1,145 @@
+/*
+ * 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.springdata22.examples.model;
+
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.cache.affinity.AffinityKey;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
+
+/**
+ * Person class.
+ */
+public class Person implements Serializable {
+ /** */
+ private static final AtomicLong ID_GEN = new AtomicLong();
+
+ /** Person ID (indexed). */
+ @QuerySqlField(index = true)
+ public Long id;
+
+ /** Organization ID (indexed). */
+ @QuerySqlField(index = true)
+ public Long orgId;
+
+ /** First name (not-indexed). */
+ @QuerySqlField
+ public String firstName;
+
+ /** Last name (not indexed). */
+ @QuerySqlField
+ public String lastName;
+
+ /** Resume text (create LUCENE-based TEXT index for this field). */
+ @QueryTextField
+ public String resume;
+
+ /** Salary (indexed). */
+ @QuerySqlField(index = true)
+ public double salary;
+
+ /** Custom cache key to guarantee that person is always collocated with its organization. */
+ private transient AffinityKey<Long> key;
+
+ /**
+ * Default constructor.
+ */
+ public Person() {
+ // No-op.
+ }
+
+ /**
+ * Constructs person record.
+ *
+ * @param org Organization.
+ * @param firstName First name.
+ * @param lastName Last name.
+ * @param salary Salary.
+ * @param resume Resume text.
+ */
+ public Person(Organization org, String firstName, String lastName, double salary, String resume) {
+ // Generate unique ID for this person.
+ id = ID_GEN.incrementAndGet();
+
+ orgId = org.id();
+
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.salary = salary;
+ this.resume = resume;
+ }
+
+ /**
+ * Constructs person record.
+ *
+ * @param id Person ID.
+ * @param orgId Organization ID.
+ * @param firstName First name.
+ * @param lastName Last name.
+ * @param salary Salary.
+ * @param resume Resume text.
+ */
+ public Person(Long id, Long orgId, String firstName, String lastName, double salary, String resume) {
+ this.id = id;
+ this.orgId = orgId;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.salary = salary;
+ this.resume = resume;
+ }
+
+ /**
+ * Constructs person record.
+ *
+ * @param id Person ID.
+ * @param firstName First name.
+ * @param lastName Last name.
+ */
+ public Person(Long id, String firstName, String lastName) {
+ this.id = id;
+
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ /**
+ * Gets cache affinity key. Since in some examples person needs to be collocated with organization, we create
+ * custom affinity key to guarantee this collocation.
+ *
+ * @return Custom affinity key to guarantee that person is always collocated with organization.
+ */
+ public AffinityKey<Long> key() {
+ if (key == null)
+ key = new AffinityKey<>(id, orgId);
+
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public String toString() {
+ return "Person [id=" + id +
+ ", orgId=" + orgId +
+ ", lastName=" + lastName +
+ ", firstName=" + firstName +
+ ", salary=" + salary +
+ ", resume=" + resume + ']';
+ }
+}
diff --git a/modules/spring-data-2.2-ext/pom.xml b/modules/spring-data-2.2-ext/pom.xml
index a7d027e..ba45cd4 100644
--- a/modules/spring-data-2.2-ext/pom.xml
+++ b/modules/spring-data-2.2-ext/pom.xml
@@ -161,4 +161,57 @@
</dependency>
</dependencies>
+ <profiles>
+ <profile>
+ <id>examples</id>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>examples/main/java</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-indexing</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-commons</artifactId>
+ <version>${spring.data-2.2.version}</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
</project>