GridGain Developers Hub

GridGain 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. GridGain supports Spring Data JDBC by implementing IgniteDialect.

Prerequisites

  • Java 17 or higher

  • Spring Boot 3.0 or higher

  • Spring Data JDBC 3.0 or higher

Limitations

  • GridGain does not auto-generate primary keys. You need to provide ID values explicitly.

  • Locking clauses (@Lock) are not supported.

  • Single query loading for related entities is not supported.

  • Composite keys are not supported.

Maven Configuration

Spring Data integration requires three dependencies:

  • spring-data-ignite provides the SQL dialect for Ignite-compatible query generation;

  • spring-boot-starter-data-jdbc provides the Spring Data JDBC framework.

The pom.xml example below shows how you can add spring support:

<repositories>
    <repository>
        <id>GridGain External Repository</id>
        <url>https://www.gridgainsystems.com/nexus/content/repositories/external</url>
    </repository>
</repositories>

<dependencies>
    <!-- GridGain Spring Data support -->
    <dependency>
        <groupId>org.gridgain</groupId>
        <artifactId>spring-data-ignite</artifactId>
        <version>9.1.17</version>
    </dependency>

    <!-- Spring Boot Starter for JDBC -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
</dependencies>

Configuration

Application Properties

Configure both the GridGain client connection and JDBC datasource in your application.properties:

# JDBC datasource configuration
spring.datasource.url=jdbc:ignite:thin://127.0.0.1:10800
spring.datasource.driver-class-name=org.apache.ignite.jdbc.IgniteJdbcDriver

Dialect Provider Registration

Spring Data JDBC needs to generate database-specific SQL for operations like pagination, identity columns, and certain functions. The spring-data-ignite artifact includes an IgniteDialectProvider that teaches Spring Data how to generate Ignite-compatible SQL.

The dialect provider is registered via Spring’s SPI mechanism. Create the file src/main/resources/META-INF/spring.factories with the following content:

org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=org.apache.ignite.data.IgniteDialectProvider

Without this configuration, Spring Data falls back to generic ANSI SQL, which works for basic queries but may fail for database-specific operations.

Defining Entities

Define entity classes that map to GridGain tables. Use standard Spring Data annotations:

import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Table("Person")
public class Person {

    @Id
    private Long id;
    private String firstName;
    private String lastName;
    private Integer age;

    // Constructors
    public Person() {}

    public Person(Long id, String firstName, String lastName, Integer age) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    // Getters and setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

Create the corresponding table in GridGain:

CREATE TABLE Person (
    id BIGINT PRIMARY KEY,
    firstName VARCHAR,
    lastName VARCHAR,
    age INT
);

Defining Repositories

Define repository interfaces by extending Spring Data repository interfaces:

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

    // Derived query methods
    List<Person> findByFirstName(String firstName);

    // ...

}

Spring Data automatically implements these methods based on their names. No additional code is required.

Using Repositories

Inject and use repositories in your Spring components:

@Service
public class PersonService {

    @Autowired
    private PersonRepository repository;

    public List<Person> findByFirstName(String firstName) {
        return repository.findByFirstName(firstName);
    }

    // ...
}

Custom Queries

For complex queries that cannot be expressed through method names, use the @Query annotation:

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

    @Query("SELECT * FROM Person WHERE age > :minAge AND lastName LIKE :pattern")
    List<Person> findByCustomQuery(@Param("minAge") Integer minAge,
                                    @Param("pattern") String pattern);

    @Query("SELECT * FROM Person WHERE firstName = ?1 OR lastName = ?2")
    List<Person> findByFirstOrLastName(String firstName, String lastName);

    @Query("SELECT COUNT(*) FROM Person WHERE age BETWEEN :minAge AND :maxAge")
    long countByAgeRange(@Param("minAge") Integer minAge,
                         @Param("maxAge") Integer maxAge);

    // Using positional parameters
    @Query("SELECT id FROM Person WHERE age > ?1 ORDER BY age DESC")
    List<Long> findIdsByAge(Integer minAge, Pageable pageable);
}

Pagination and Sorting

GridGain supports pagination and sorting through Spring Data’s standard interfaces:

Sorting

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

    // Method name-based sorting
    List<Person> findByLastNameOrderByAgeDesc(String lastName);

    // Using Sort parameter
    List<Person> findByLastName(String lastName, Sort sort);

    Iterable<Person> findAll(Sort sort);
}

// Usage
List<Person> persons = repository.findByLastName("Smith",
    Sort.by(Sort.Direction.DESC, "age"));

List<Person> allPersons = (List<Person>) repository.findAll(
    Sort.by("lastName").ascending()
        .and(Sort.by("firstName").ascending())
);

Pagination

@Repository
public interface PersonRepository extends PagingAndSortingRepository<Person, Long>,
                                          CrudRepository<Person, Long> {

    // Page-based pagination
    Page<Person> findByLastName(String lastName, Pageable pageable);

    // Slice-based pagination (no total count)
    Slice<Person> findByFirstName(String firstName, Pageable pageable);
}

// Usage
@Service
public class PersonService {

    @Autowired
    private PersonRepository repository;

    public Page<Person> getPersonsPage(int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("lastName"));
        return repository.findByLastName("Smith", pageable);
    }

    public List<Person> getFirstPage() {
        Pageable pageable = PageRequest.of(0, 10);
        Page<Person> page = repository.findAll(pageable);

        System.out.println("Total elements: " + page.getTotalElements());
        System.out.println("Total pages: " + page.getTotalPages());
        System.out.println("Current page: " + page.getNumber());

        return page.getContent();
    }
}

Authentication

When authentication is enabled on the GridGain cluster, configure credentials for both the client and JDBC connections:

# GridGain client authentication
ignite.client.addresses=127.0.0.1:10800
ignite.client.auth.basic.username=myuser
ignite.client.auth.basic.password=mypassword

# JDBC datasource with authentication
spring.datasource.url=jdbc:ignite:thin://127.0.0.1:10800
spring.datasource.driver-class-name=org.apache.ignite.jdbc.IgniteJdbcDriver
spring.datasource.username=myuser
spring.datasource.password=mypassword