7. Gemfire Repositories

7.1 Introduction

Spring Data Gemfire provides support to use the Spring Data repository abstraction to easily persist entities into Gemfire and execute queries. A general introduction into the repository programmin model has been provided in Chapter 6, Repositories.

7.2 Spring configuration

To bootstrap Spring Data repositories you use the <repositories /> element from the Gemfire namespace:

Example 7.1. Bootstrap Gemfire repositories

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:gf="http://www.springframework.org/schema/gemfire"
       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
                           http://www.springframework.org/schema/gemfire 
                           http://www.springframework.org/schema/gemfire/spring-gemfire.xsd>

  <gf:repositories base-package="com.acme.repository" />

</beans>

This configuration snippet will look for interfaces below the configured base package and create repository instances for those interfaces backed by a SimpleGemfireRepository. Note that you have to have your domain classes correctly mapped to configured regions as the bottstrap process will fail otherwise.

7.3 Executing OQL queries

The Gemfire repositories allow the definition of query methods to easily execute OQL queries against the Region the managed entity is mapped to.

Example 7.2. Sample repository

@Region("myRegion")
public class Person { … }
public interface PersonRepository extends CrudRepository<Person, Long> {

  Person findByEmailAddress(String emailAddress);

  Collection<Person> findByFirstname(String firstname);

  @Query("SELECT * FROM /Person p WHERE p.firstname = $1")
  Collection<Person> findByFirstnameAnnotated(String firstname);

  @Query("SELECT * FROM /Person p WHERE p.firstname IN SET $1")
  Collection<Person> findByFirstnamesAnnotated(Collection<String> firstnames);
}

The first method listed here will cause the following query to be derived: SELECT x FROM /myRegion x WHERE x.emailAddress = $1. The second method works the same way except it's returning all entities found whereas the first one expects a single result value. In case the supported keywords are not sufficient to declare your query or the method name gets to verbose you can annotate the query methods with @Query as seen for methods 3 and 4.

Table 7.1. Supported keywords for query methods

KeywordSampleLogical result
GreaterThanfindByAgeGreaterThan(int age)x.age > $1
GreaterThanEqualfindByAgeGreaterThanEqual(int age)x.age >= $1
LessThanfindByAgeLessThan(int age)x.age < $1
LessThanEqualfindByAgeLessThanEqual(int age)x.age <= $1
IsNotNull, NotNullfindByFirstnameNotNull()x.firstname =! NULL
IsNull, NullfindByFirstnameNull()x.firstname = NULL
InfindByFirstnameIn(Collection<String> x)x.firstname IN SET $1
NotInfindByFirstnameNotIn(Collection<String> x)x.firstname NOT IN SET $1
(No keyword)findByFirstname(String name)x.firstname = $1
NotfindByFirstnameNot(String name)x.firstname != $1
IsTrue, TruefindByActiveIsTrue()x.active = true
IsFalse, FalsefindByActiveIsFalse()x.active = false