Querying Data with Ickle and Protobuf
What You Will Learn
How to define Protobuf schemas with @Proto annotations, create indexed caches, and run Ickle queries including WHERE clauses, projections, and DELETE operations.
Prerequisites
-
Java 17+
-
An Infinispan Server running on
localhost:11222(or Docker/Podman available for Testcontainers)
Step 1: Define Your Data Model with Protobuf Annotations
Infinispan uses Protobuf for serialization. Define your entities as Java records with @Proto and @Indexed annotations.
The Person entity uses @Keyword annotations for indexed fields, and the PersonKey record defines a composite key with @Basic projectable fields. A @ProtoSchema interface generates the schema for both:
@Proto
@Indexed(keyEntity = "tutorial.PersonKey")
public record Person(@Keyword(projectable = true, sortable = true, normalizer = "lowercase", indexNullAs = "unnamed", norms = false)
String firstName,
@Keyword(projectable = true, sortable = true, normalizer = "lowercase", indexNullAs = "unnamed", norms = false)
String lastName,
int bornYear,
@Keyword(projectable = true, sortable = true, normalizer = "lowercase", indexNullAs = "unnamed", norms = false)
String bornIn
) {}
Step 2: Connect and Create an Indexed Cache
Register the Protobuf context initializer, configure the indexed cache with indexing enabled="true", and connect:
static void connectToInfinispan() throws Exception {
ConfigurationBuilder builder = TutorialsConnectorHelper.connectionConfig();
// Add the Protobuf serialization context in the client
builder.addContextInitializer(new TutorialSchemaImpl());
// Use indexed cache
URI indexedCacheURI = InfinispanRemoteQuery.class.getClassLoader().getResource("indexedCache.xml").toURI();
builder.remoteCache(INDEXED_PEOPLE_CACHE).configurationURI(indexedCacheURI);
// Connect to the server
client = TutorialsConnectorHelper.connect(builder);
// Create and add the Protobuf schema in the server
addPersonSchema(client);
// Get the people cache, create it if needed with the default configuration
peopleCache = client.getCache(INDEXED_PEOPLE_CACHE);
}
Step 3: Run Ickle Queries
Query all entries, filter with parameters, use projections, and delete by query:
static List<Person> queryAll() {
// Query all
Query<Person> query = peopleCache.query("FROM tutorial.Person");
List<Person> queryResult = query.execute().list();
// Print the results
System.out.println("SIZE " + queryResult.size());
System.out.println(queryResult);
return queryResult;
}
static List<Person> queryWithWhereStatementOnValues() {
// Create a query with lastName parameter
System.out.println("== Query on values");
Query<Person> query = peopleCache.query("FROM tutorial.Person p where p.lastName = :lastName");
// Set the parameter value
query.setParameter("lastName", "Granger");
// Execute the query
List<Person> queryResult = query.execute().list();
// Print the results
System.out.println(queryResult);
return queryResult;
}
static List<PersonDTO> queryWithProjection() {
// Create a query with projection
System.out.println("== Query with key and values projection");
Query<Object[]> queryProjection = peopleCache.query("SELECT p.key.pseudo, p.firstName, p.lastName FROM tutorial.Person p where p.bornIn = 'London'");
// Execute the queryProjection
List<PersonDTO> queryResultProjection = queryProjection.execute().list()
.stream()
.map(r -> new PersonDTO(r[0] + "", r[1] + " " + r[2]))
.toList();
// Print the results queryResultProjection
System.out.println(queryResultProjection);
return queryResultProjection;
}
static List<Person> deleteByQuery() {
Query<Person> query = peopleCache.query("DELETE FROM tutorial.Person p where p.key.pseudo = 'dmalfoy'");
System.out.println("== DELETE count:" + query.execute().count().value());
// Query all
query = peopleCache.query("FROM tutorial.Person");
List<Person> queryResult = query.execute().list();
// Print the results
System.out.println("SIZE " + queryResult.size());
System.out.println(queryResult);
return queryResult;
}
Step 4: Run the Tutorial
mvn package exec:java
What’s Next
-
Try spatial queries for geolocation data
-
Add continuous queries for real-time notifications


