Spring Boot Automatic Protobuf Schema Registration
What You Will Learn
How to use the Infinispan Spring Boot starter with automatic Protobuf schema registration.
Starting with Infinispan 16.2, the starter automatically discovers GeneratedSchema implementations on the classpath, registers them as serialization context initializers, and uploads the schemas to the Infinispan Server at startup.
No manual schemas().createOrUpdate() call is needed.
This tutorial builds a REST application that stores indexed characters in a remote cache and performs full-text search queries.
Prerequisites
-
Java 17+
-
Spring Boot
-
Docker or Podman (optional)
You can start an Infinispan Server manually with Docker or Podman:
docker run -it --rm -p 11222:11222 -e USER=admin -e PASS=password quay.io/infinispan/server:latest
|
Tip
|
You can replace docker with podman in the command above if you use Podman.
|
|
Tip
|
If no server is running on localhost:11222, the application automatically starts an Infinispan container using Testcontainers.
|
Step 1: Add Dependencies
Add the Infinispan Spring Boot remote starter and the ProtoStream annotation processor:
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring-boot4-starter-remote</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan.protostream</groupId>
<artifactId>protostream-processor</artifactId>
</dependency>
Step 2: Configure the Connection and Cache
In application.properties, configure the connection, the marshaller, and the cache definition:
infinispan.remote.connection-uri=hotrod://admin:password@127.0.0.1:11222
# Per-cache configuration: point to the cache XML definition and ProtoStreamMarshaller marshaller
infinispan.remote.cache.characters.configuration-uri=classpath:indexedCache.xml
infinispan.remote.cache.characters.marshaller=org.infinispan.commons.marshall.ProtoStreamMarshaller
characters.filename=characters.csv
# Protobuf schemas are automatically discovered and uploaded to the server at startup.
# To disable this behavior, uncomment the following property:
# infinispan.remote.use-schema-registration=false
Key points:
-
infinispan.remote.connection-uriprovides the connection string including credentials. -
infinispan.remote.cache.characters.configuration-uripoints to a classpath XML file that defines the cache. -
infinispan.remote.cache.characters.marshalleris set toProtoStreamMarshallerbecause the default isJavaSerializationMarshaller. -
There is no manual schema registration code. The starter automatically discovers and uploads Protobuf schemas at startup.
-
To disable auto schema upload, set
infinispan.remote.use-schema-registration=false.
Step 3: Define a Protobuf Entity
Create an indexed Protobuf record with @Text fields for full-text search:
@Proto
@Indexed
public record Character(UUID id, @Text String name, @Text String bio, Archetype archetype) {
}
Step 4: Define the Protobuf Schema
Create a @ProtoSchema interface that extends GeneratedSchema.
The starter will discover this interface automatically on the classpath, register it with the serialization context, and upload the generated .proto schema to the server:
@ProtoSchema(schemaPackageName = "tutorial",
includeClasses = {Character.class, Archetype.class},
dependsOn = {
org.infinispan.protostream.types.java.CommonTypes.class
})
public interface AppSchema extends GeneratedSchema {
}
Step 5: Query the Cache
Inject the RemoteCacheManager and perform full-text queries using Ickle:
@Service
public class CharacterSearch {
private final RemoteCache<String, Character> characters;
public CharacterSearch(RemoteCacheManager remoteCacheManager) {
this.characters = remoteCacheManager.getCache("characters");
}
public Character getById(String id) {
return characters.get(id);
}
public Set<String> search(String term) {
String query = "FROM tutorial.Character c"
+ " WHERE c.name:'~" + term + "'"
+ " OR c.bio: '~" + term + "'";
List<Character> result = characters.<Character>query(query).execute().list();
return result.stream().map(Character::name).collect(Collectors.toSet());
}
}
Step 6: Expose REST Endpoints
Create a Spring @RestController that exposes the search service:
@RestController
@RequestMapping("/characters")
public class CharactersResource {
private final CharacterSearch searchService;
public CharactersResource(CharacterSearch searchService) {
this.searchService = searchService;
}
@GetMapping("/{id}")
public Character byId(@PathVariable("id") String id) {
Character character = searchService.getById(id);
if (character == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND,
"Character with id of " + id + " does not exist.");
}
return character;
}
@GetMapping("/query")
public Set<String> searchCharacter(@RequestParam(value = "term", required = false) String term) {
if (term == null) {
return Collections.emptySet();
}
return searchService.search(term);
}
}
Step 7: Run the Tutorial
mvn spring-boot:run
Then query the REST endpoints:
curl http://localhost:8080/characters/0
curl "http://localhost:8080/characters/query?term=Felix"
How Auto Schema Registration Works
The Infinispan Spring Boot starter (16.2+) automatically:
-
Scans your application packages for
GeneratedSchemaimplementations using Spring’s classpath scanning. -
Registers them as
SerializationContextInitializerinstances with theRemoteCacheManager. -
Uploads the
.protoschemas to the Infinispan Server viaRemoteSchemasAdmin.createOrUpdate().
This is controlled by the infinispan.remote.use-schema-registration property, which defaults to true.
|
Note
|
The auto-discovery scans packages registered with Spring Boot’s AutoConfigurationPackages and skips internal Infinispan packages (org.infinispan.*).
Make sure your application uses a different base package so the scanner picks up your schema.
|
What’s Next
-
Spring Boot remote caching for caching with
@Cacheableand@CacheEvict -
Quarkus Infinispan Client for the same pattern with Quarkus


