Programmatic Index Configuration with Embedded Infinispan

What You Will Learn

How to define search index mappings programmatically using ProgrammaticSearchMappingProvider instead of annotations, allowing you to index plain Java records or classes without modifying their source.

Prerequisites

  • Java 17+

Step 1: Add Dependencies

Add the Infinispan core and query modules to your pom.xml:

<dependency>
   <groupId>org.infinispan</groupId>
   <artifactId>infinispan-core</artifactId>
</dependency>
<dependency>
   <groupId>org.infinispan</groupId>
   <artifactId>infinispan-query</artifactId>
</dependency>

Step 2: Define a Plain Entity

Use a simple Java record with no indexing annotations:

public record Person(String name, String surname) {
}

Step 3: Create a Programmatic Index Definition

Implement ProgrammaticSearchMappingProvider to define the index mapping in code:

public class PersonIndexDefinition implements ProgrammaticSearchMappingProvider {

    @Override
    public void configure(MappingConfigurationContext context) {
        ProgrammaticMappingConfigurationContext programmaticMappingConfigurationContext = context.programmaticMapping();
        TypeMappingStep type = programmaticMappingConfigurationContext.type(Person.class);
        type.indexed().enabled(true);
        type.property("name").fullTextField();
        type.property("surname").fullTextField();
    }
}

Step 4: Register the Provider via SPI

Create a service file at META-INF/services/org.infinispan.search.mapper.mapping.ProgrammaticSearchMappingProvider containing:

org.infinispan.tutorial.simple.query.programmatic.PersonIndexDefinition

Step 5: Run a Full-Text Query

Configure an indexed cache and query using full-text syntax with wildcards:

      // Create cache config
      ConfigurationBuilder builder = new ConfigurationBuilder();
      builder.indexing()
              .enable()
              .storage(IndexStorage.LOCAL_HEAP)
              .addIndexedEntity(Person.class);

      // Obtain the cache
      cache = cacheManager.administration()
              .withFlags(CacheContainerAdmin.AdminFlag.VOLATILE)
              .getOrCreateCache("cache", builder.build());
      // Store some entries
      cache.put("person1", new Person("William", "Shakespeare"));
      cache.put("person2", new Person("William", "Wordsworth"));
      cache.put("person3", new Person("John", "Milton"));
      // Construct a query
      Query<Person> query = cache.query("from org.infinispan.tutorial.simple.query.programmatic.Person where name : 'Will*'");
      // Execute the query
      return query.execute().list();

Step 6: Run the Tutorial

mvn package exec:java

The output shows the two persons whose name matches the wildcard Will*.

What’s Next