Spring Boot auto-configuration for chat memory functionality in Spring AI applications
Comprehensive configuration options for Spring AI Chat Memory.
Control how many messages are retained per conversation:
@Configuration
public class ChatMemoryConfiguration {
@Bean
public ChatMemory chatMemory(ChatMemoryRepository repository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(repository)
.maxMessages(50) // Keep last 50 messages
.build();
}
}Override the default in-memory repository:
@Configuration
public class ChatMemoryConfiguration {
@Bean
public ChatMemoryRepository chatMemoryRepository(DataSource dataSource) {
return JdbcChatMemoryRepository.builder()
.dataSource(dataSource)
.build();
}
}# Schema initialization
spring.ai.chat.memory.repository.jdbc.initialize-schema=always
# Options: EMBEDDED, ALWAYS, NEVER
# Database platform (auto-detected if not specified)
spring.ai.chat.memory.repository.jdbc.platform=postgresql
# Options: postgresql, mysql, h2, oracle, sqlserver, mariadb, hsqldb, sqlite
# Custom schema location
spring.ai.chat.memory.repository.jdbc.schema=classpath:custom-schema.sql@Configuration
public class JdbcChatMemoryConfiguration {
@Bean
public ChatMemoryRepository jdbcChatMemoryRepository(
JdbcTemplate jdbcTemplate,
DataSource dataSource) {
return JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.dataSource(dataSource) // For dialect auto-detection
.build();
}
}@Bean
public ChatMemoryRepository jdbcChatMemoryRepository(JdbcTemplate jdbcTemplate) {
JdbcChatMemoryRepositoryDialect dialect =
JdbcChatMemoryRepositoryDialect.from(dataSource);
return JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.dialect(dialect)
.build();
}# Enable automatic index creation
spring.ai.chat.memory.repository.mongo.create-indices=true
# Set time-to-live for conversations
spring.ai.chat.memory.repository.mongo.ttl=PT24H
# Examples: PT1H (1 hour), P7D (7 days), P30D (30 days)@Configuration
public class MongoChatMemoryConfiguration {
@Bean
public ChatMemoryRepository mongoChatMemoryRepository(MongoTemplate mongoTemplate) {
return MongoChatMemoryRepository.builder()
.mongoTemplate(mongoTemplate)
.build();
}
}# Keyspace configuration
spring.ai.chat.memory.repository.cassandra.keyspace=my_keyspace
# Table configuration
spring.ai.chat.memory.repository.cassandra.table=chat_memory
spring.ai.chat.memory.repository.cassandra.messages-column=messages
# Schema initialization
spring.ai.chat.memory.repository.cassandra.initialize-schema=true
# Time-to-live
spring.ai.chat.memory.repository.cassandra.time-to-live=P30D@Configuration
public class CassandraChatMemoryConfiguration {
@Bean
public ChatMemoryRepository cassandraChatMemoryRepository(CqlSession cqlSession) {
CassandraChatMemoryRepositoryConfig config =
CassandraChatMemoryRepositoryConfig.builder()
.withCqlSession(cqlSession)
.withKeyspaceName("my_app")
.withTableName("conversations")
.withTimeToLive(Duration.ofDays(30))
.build();
return CassandraChatMemoryRepository.create(config);
}
}@Bean
public ChatMemoryRepository cassandraChatMemoryRepository(CqlSession cqlSession) {
CassandraChatMemoryRepositoryConfig config =
CassandraChatMemoryRepositoryConfig.builder()
.withCqlSession(cqlSession)
.withKeyspaceName("my_keyspace")
.withTableName("chat_memory")
.withMessagesColumnName("message_data")
.withTimeToLive(Duration.ofDays(90))
.disallowSchemaChanges() // Schema must exist
.build();
return CassandraChatMemoryRepository.create(config);
}# Node label configuration
spring.ai.chat.memory.repository.neo4j.session-label=ChatSession
spring.ai.chat.memory.repository.neo4j.message-label=ChatMessage
spring.ai.chat.memory.repository.neo4j.metadata-label=Metadata
spring.ai.chat.memory.repository.neo4j.tool-call-label=ToolCall
spring.ai.chat.memory.repository.neo4j.tool-response-label=ToolResponse
spring.ai.chat.memory.repository.neo4j.media-label=Media@Configuration
public class Neo4jChatMemoryConfiguration {
@Bean
public ChatMemoryRepository neo4jChatMemoryRepository(Driver driver) {
Neo4jChatMemoryRepositoryConfig config =
Neo4jChatMemoryRepositoryConfig.builder()
.withDriver(driver)
.withSessionLabel("ChatSession")
.withMessageLabel("ChatMessage")
.build();
return new Neo4jChatMemoryRepository(config);
}
}# Connection configuration
spring.ai.chat.memory.repository.cosmosdb.endpoint=https://myaccount.documents.azure.com:443/
spring.ai.chat.memory.repository.cosmosdb.key=your-account-key
# Connection mode
spring.ai.chat.memory.repository.cosmosdb.connection-mode=direct
# Options: gateway, direct
# Database and container
spring.ai.chat.memory.repository.cosmosdb.database-name=chat_memory_db
spring.ai.chat.memory.repository.cosmosdb.container-name=conversations
# Partition key
spring.ai.chat.memory.repository.cosmosdb.partition-key-path=/conversationId@Configuration
public class CosmosDBChatMemoryConfiguration {
@Bean
public ChatMemoryRepository cosmosDBChatMemoryRepository(CosmosAsyncClient client) {
CosmosDBChatMemoryRepositoryConfig config =
CosmosDBChatMemoryRepositoryConfig.builder()
.withCosmosClient(client)
.withDatabaseName("chat_db")
.withContainerName("conversations")
.withPartitionKeyPath("/conversationId")
.build();
return CosmosDBChatMemoryRepository.create(config);
}
}Use different repositories for different purposes:
@Configuration
public class MultiRepositoryConfiguration {
@Bean("shortTermMemory")
public ChatMemory shortTermMemory() {
// In-memory for temporary conversations
return MessageWindowChatMemory.builder()
.chatMemoryRepository(new InMemoryChatMemoryRepository())
.maxMessages(10)
.build();
}
@Bean("longTermMemory")
@Primary
public ChatMemory longTermMemory(DataSource dataSource) {
// JDBC for persistent conversations
ChatMemoryRepository repository = JdbcChatMemoryRepository.builder()
.dataSource(dataSource)
.build();
return MessageWindowChatMemory.builder()
.chatMemoryRepository(repository)
.maxMessages(100)
.build();
}
}# Use in-memory for fast development
# No additional configuration needed - uses defaults# Use H2 for integration tests
spring.ai.chat.memory.repository.jdbc.initialize-schema=always
spring.ai.chat.memory.repository.jdbc.platform=h2# Use PostgreSQL for production
spring.ai.chat.memory.repository.jdbc.initialize-schema=never
spring.ai.chat.memory.repository.jdbc.platform=postgresql
# Or MongoDB with TTL
spring.ai.chat.memory.repository.mongo.create-indices=true
spring.ai.chat.memory.repository.mongo.ttl=P7D@Configuration
public class TransactionalChatMemoryConfiguration {
@Bean
public ChatMemoryRepository jdbcChatMemoryRepository(
JdbcTemplate jdbcTemplate,
DataSource dataSource,
PlatformTransactionManager transactionManager) {
return JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.dataSource(dataSource)
.transactionManager(transactionManager)
.build();
}
}# Connection pool settings
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000spring.data.mongodb.uri=mongodb://localhost:27017/chatmemory?maxPoolSize=50&minPoolSize=10@Bean
public CosmosAsyncClient cosmosAsyncClient() {
return new CosmosClientBuilder()
.endpoint(cosmosEndpoint)
.credential(new DefaultAzureCredentialBuilder().build())
.buildAsyncClient();
}spring.datasource.url=jdbc:postgresql://localhost:5432/chatmemory?ssl=true
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}management.endpoints.web.exposure.include=health,metrics
management.endpoint.health.show-details=always@Component
public class ChatMemoryHealthIndicator implements HealthIndicator {
@Autowired
private ChatMemoryRepository repository;
@Override
public Health health() {
try {
repository.findConversationIds();
return Health.up().build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}# application-dev.properties
# In-memory configuration
# application-prod.properties
# Persistent repository configuration# Use environment variables
spring.ai.chat.memory.repository.cosmosdb.key=${COSMOS_DB_KEY}
spring.datasource.password=${DB_PASSWORD}// Small for quick interactions
.maxMessages(10)
// Medium for standard conversations
.maxMessages(50)
// Large for extended sessions
.maxMessages(200)# Development: always
spring.ai.chat.memory.repository.jdbc.initialize-schema=always
# Production: never (use migration tools)
spring.ai.chat.memory.repository.jdbc.initialize-schema=never# MongoDB: 24 hours
spring.ai.chat.memory.repository.mongo.ttl=PT24H
# Cassandra: 30 days
spring.ai.chat.memory.repository.cassandra.time-to-live=P30DProblem: Tables not created automatically.
Solution:
spring.ai.chat.memory.repository.jdbc.initialize-schema=alwaysProblem: Database connection times out.
Solution: Increase timeout and check network:
spring.datasource.hikari.connection-timeout=60000Problem: Indices not created on startup.
Solution: Enable index creation:
spring.ai.chat.memory.repository.mongo.create-indices=truetessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-model-chat-memory@1.1.0