Spring AI Chat Memory with Infinispan
What You Will Learn
How to use Infinispan as a Spring AI ChatMemoryRepository to persist chat conversations.
Messages are stored in an indexed Infinispan cache, supporting retrieval by conversation ID, listing all conversations, and deletion.
Prerequisites
-
Java 17+
-
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 AI chat memory repository auto-configuration:
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>spring-ai-autoconfigure-model-chat-memory-repository-infinispan</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>spring-ai-model-chat-memory-repository-infinispan</artifactId>
</dependency>
The auto-configuration creates the ChatMemoryRepository bean, registers the Protobuf schema, and creates the indexed cache automatically.
Step 2: Configure the Connection
In application.properties, configure the Infinispan connection:
infinispan.remote.server-list=127.0.0.1:11222
infinispan.remote.auth-username=admin
infinispan.remote.auth-password=password
Step 3: Save Messages
Inject the ChatMemoryRepository and save user and assistant messages to a conversation:
@PostMapping(path = "/conversations/{conversationId}")
public String addMessages(@PathVariable String conversationId,
@RequestParam String userMessage,
@RequestParam String assistantMessage) {
List<Message> messages = List.of(
new UserMessage(userMessage),
AssistantMessage.builder().content(assistantMessage).build());
chatMemoryRepository.saveAll(conversationId, messages);
return "Saved " + messages.size() + " messages to conversation " + conversationId;
}
Step 4: Retrieve Conversations
List all conversation IDs or retrieve all messages for a specific conversation:
@GetMapping(path = "/conversations")
public List<String> listConversations() {
return chatMemoryRepository.findConversationIds();
}
@GetMapping(path = "/conversations/{conversationId}")
public List<MessageResponse> getConversation(@PathVariable String conversationId) {
return chatMemoryRepository.findByConversationId(conversationId).stream()
.map(m -> new MessageResponse(m.getMessageType().name(), m.getText()))
.toList();
}
Step 5: Delete Conversations
Remove all messages for a conversation:
@DeleteMapping(path = "/conversations/{conversationId}")
public String deleteConversation(@PathVariable String conversationId) {
chatMemoryRepository.deleteByConversationId(conversationId);
return "Deleted conversation " + conversationId;
}
Step 6: Run the Tutorial
mvn spring-boot:run
Then interact with the REST API:
curl -X POST "http://localhost:8080/conversations/chat-1?userMessage=What+is+Infinispan&assistantMessage=A+distributed+data+store"
curl http://localhost:8080/conversations
curl http://localhost:8080/conversations/chat-1
curl -X DELETE http://localhost:8080/conversations/chat-1
What’s Next
-
Try Spring AI Vector Store to use Infinispan for semantic search
-
Try LangChain4j Embedding Store for vector search without Spring AI


