Apache Ignite With Spring Data | Ignite Documentation

Ignite Summit 2024 — Call For Speakers Now Open — Learn more

Edit

Apache Ignite With Spring Data

Overview

Spring Data Framework provides a unified and widely used API that allows abstracting an underlying data storage from the application layer. Spring Data helps you avoid locking to a specific database vendor, making it easy to switch from one database to another with minimal efforts. Apache Ignite integrates with Spring Data by implementing Spring Data CrudRepository interface.

Maven Configuration

The easiest way to start working with Apache Ignite’s Spring Data repository is by adding the following Maven dependencies to the application’s pom.xml file:

<dependency>
    <groupId>org.apache.ignite</groupId>
    <artifactId>ignite-spring-data-ext</artifactId>
    <version>${ignite-spring-data-ext.version}</version>
</dependency>

<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.version}</version>
</dependency>

Replace ${ignite-spring-data-ext.version}, ${spring.data.version}, and ${ignite.version} with an actual version of Apache Ignite Spring Data extension, Spring Data, and Apache Ignite dependencies you are interested in, respectively.

The table below shows available versions of the Apache Ignite Spring Data extension and corresponding versions of the Apache Ignite each one is compatible with.

Apache Ignite Spring Data extension version Compatible Apache Ignite versions

1.0.0

All versions since 2.8.0

2.0.0

All versions since 2.8.0

Note

If your Spring Data version is earlier than Spring Data 2.2 then set ignite-spring-data-2.0-ext or ignite-spring-data-ext as an artifactId in the pom.xml configuration.

Apache Ignite Repository

Apache Ignite introduces a special IgniteRepository interface that extends default CrudRepository. This interface should be extended by all custom Spring Data repositories that wish to store and query data located in an Apache Ignite cluster.

For instance, let’s create the first custom repository named PersonRepository:

@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);
}
  • @RepositoryConfig annotation should be specified to map a repository to a distributed cache. In the above example, PersonRepository is mapped to PersonCache.

  • Signatures of custom methods like findByFirstName(name) and findTopByLastNameLike(name) will be automatically processed and turned into SQL queries when methods get executed. In addition, @Query(queryString) annotation can be used if a concrete​ SQL query needs to be executed as a result of a method call.

Caution

Unsupported CRUD Operations

Some operations of CrudRepository interface are not currently supported. These are the operations that do not require providing the key as a parameter:

  • save(S entity)

  • save(Iterable<S> entities)

  • delete(T entity)

  • delete(Iterable<? extends T> entities)

Instead of these operations you can use Ignite specific counterparts available via IgniteRepository interface:

  • save(ID key, S entity)

  • save(Map<ID, S> entities)

  • deleteAll(Iterable<ID> ids)

Spring Data and Apache Ignite Configuration

Apache Ignite Spring Data integration supports connecting to the Apache Ignite cluster through the Apache Ignite node or Apache Ignite thin client. Both approaches to configuring access to the Apache Ignite cluster use the same API shown below. Apache Ignite Spring Data integration automatically recognizes the type of the provided bean and uses the appropriate cluster connection.

To enable Apache Ignite backed repositories in Spring Data, mark an application configuration with @EnableIgniteRepositories annotation, as shown below:

@Configuration
@EnableIgniteRepositories
public class SpringAppCfg {
    /**
     * Creating Apache Ignite instance bean. A bean will be passed
     * to IgniteRepositoryFactoryBean to initialize all Ignite based Spring Data repositories and connect to a cluster.
     */
    @Bean
    public Ignite igniteInstance() {
        IgniteConfiguration cfg = new IgniteConfiguration();

        // Setting some custom name for the node.
        cfg.setIgniteInstanceName("springDataNode");

        // Enabling peer-class loading feature.
        cfg.setPeerClassLoadingEnabled(true);

        // Defining and creating a new cache to be used by Ignite Spring Data
        // repository.
        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");

        // Setting SQL schema for the cache.
        ccfg.setIndexedTypes(Long.class, Person.class);

        cfg.setCacheConfiguration(ccfg);

        return Ignition.start(cfg);
    }
}
@Configuration
@EnableIgniteRepositories
public class SpringAppCfg {
    /**
     * Creating Apache Ignite thin client instance bean. A bean will be passed to the IgniteRepositoryFactoryBean to
     * connect to the Ignite cluster and perform cache operations.
     */
    @Bean
    public IgniteClient igniteInstance() {
        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800");;
    }
}

The configuration has to instantiate the Apache Ignite bean (node) or the Apache Ignite thin client bean that is passed to IgniteRepositoryFactoryBean and is used by all the Apache Ignite repositories in order to connect to the cluster.

In the example above, the bean is initialized directly by the application and is named igniteInstance. Alternatively, the following beans can be registered in your configuration and an Apache Ignite node will be started automatically:

  • IgniteConfiguration object named as igniteCfg bean.

  • A path to Apache Ignite’s Spring XML configuration named igniteSpringCfgPath.

In the case of connecting to the cluster via Apache Ignite thin client, you can alternatively register the ClientConfiguration bean named igniteCfg, so that the Apache Ignite thin client instance is started automatically by the Apache Ignite Spring Data integration.

Using Apache Ignite Repositories

Once all the configurations and repositories are ready to be used, you can register the configuration in an application context and get a reference to the repository. The following example shows how to register SpringAppCfg - our sample configuration from the section above - in an application context and get a reference to PersonRepository:

ctx = new AnnotationConfigApplicationContext();

// Explicitly registering Spring configuration.
ctx.register(SpringAppCfg.class);

ctx.refresh();

// Getting a reference to PersonRepository.
repo = ctx.getBean(PersonRepository.class);

Now, you can put data in Ignite using Spring Data API:

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"));

// Adding data into the repository.
repo.save(persons);

To query the data, we can use basic CRUD operations or methods that will be automatically turned into Apache Ignite SQL queries:

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());

Example

The complete example is available on GitHub, windows="_blank"

Tutorial

Follow the tutorial that shows how to build a RESTful web service with Apache Ignite and Spring Data.