APPLICATION FAILED TO START when create-indices = true

Bug description

The property spring.ai.chat.memory.repository.mongo.create-indices = true causes the following error:

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration.initIndicesAfterStartup(MongoChatMemoryIndexCreatorAutoConfiguration.java:61)

The following method did not exist:

    'java.lang.String org.springframework.data.mongodb.core.index.IndexOperations.createIndex(org.springframework.data.mongodb.core.index.IndexDefinition)'

The calling method's class, org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration, was loaded from the following location:

    jar:file:/C:/Users/wbertolasi/.m2/repository/org/springframework/ai/spring-ai-autoconfigure-model-chat-memory-repository-mongodb/1.1.0/spring-ai-autoconfigure-model-chat-memory-repository-mongodb-1.1.0.jar!/org/springframework/ai/model/chat/memory/repository/mongo/autoconfigure/MongoChatMemoryIndexCreatorAutoConfiguration.class

The called method's class, org.springframework.data.mongodb.core.index.IndexOperations, is available from the following locations:

    jar:file:/C:/Users/wbertolasi/.m2/repository/org/springframework/data/spring-data-mongodb/4.2.4/spring-data-mongodb-4.2.4.jar!/org/springframework/data/mongodb/core/index/IndexOperations.class

The called method's class hierarchy was loaded from the following locations:

    org.springframework.data.mongodb.core.index.IndexOperations: file:/C:/Users/wbertolasi/.m2/repository/org/springframework/data/spring-data-mongodb/4.2.4/spring-data-mongodb-4.2.4.jar

Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration and org.springframework.data.mongodb.core.index.IndexOperations

Environment

  • Spring AI version: 1.1.0
  • Java version: 17
  • SpringBoot version: 3.2.4
  • Database: MongoDB v7.0
  • Schema/driver: Spring Data MongoDB + MongoTemplate

Relevant configuration:

spring:
  ai:
    chat:
      memory:
        repository:
          mongo:
            create-indices: true
            ttl: 20000
<!-- MongoDB -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

        <!-- ############### BEGIN: SPRING AI ############### -->

        <!-- Spring AI (Chat, OpenAI Model, Chat Memory, AI Agent) -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-client-chat</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-chat-memory</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-chat-memory-repository-mongodb</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!-- MCP CLIENT -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!-- ############### END: SPRING AI ############### -->

where: spring-ai.version=1.1.0

I have also tried to use newer version of spring-data-mongodb (4.3.x or more) and the error becomes: the following:

java.lang.IllegalStateException: Failed to introspect Class [org.springframework.data.mongodb.core.convert.MappingMongoConverter] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@1d44bcfa] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-6.1.5.jar:6.1.5] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:360) ~[spring-core-6.1.5.jar:6.1.5] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:342) ~[spring-core-6.1.5.jar:6.1.5] at org.springframework.ai.mcp.annotation.spring.AbstractClientMcpHandlerRegistry.scan(AbstractClientMcpHandlerRegistry.java:128) ~[spring-ai-mcp-annotations-1.1.0.jar:1.1.0] at org.springframework.ai.mcp.annotation.spring.AbstractClientMcpHandlerRegistry.postProcessBeanFactory(AbstractClientMcpHandlerRegistry.java:77) ~[spring-ai-mcp-annotations-1.1.0.jar:1.1.0] at org.springframework.ai.mcp.annotation.spring.ClientMcpSyncHandlersRegistry.postProcessBeanFactory(ClientMcpSyncHandlersRegistry.java:65) ~[spring-ai-mcp-annotations-1.1.0.jar:1.1.0] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:363) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:204) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.4.jar:3.2.4] at com.fw.ai_mcp_client.AiMcpClientApplication.main(AiMcpClientApplication.java:25) ~[classes/:na] Caused by: java.lang.NoClassDefFoundError: org/springframework/data/mapping/model/ValueExpressionEvaluator at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na] at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) ~[na:na] at java.base/java.lang.Class.getDeclaredMethods(Class.java:2504) ~[na:na] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465) ~[spring-core-6.1.5.jar:6.1.5] ... 16 common frames omitted Caused by: java.lang.ClassNotFoundException: org.springframework.data.mapping.model.ValueExpressionEvaluator at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na] ... 20 common frames omitted con spring data mongo db 4.2.12 ottengo An attempt was made to call a method that does not exist. The attempt was made from the following location: org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration.initIndicesAfterStartup(MongoChatMemoryIndexCreatorAutoConfiguration.java:61) The following method did not exist: 'java.lang.String org.springframework.data.mongodb.core.index.IndexOperations.createIndex(org.springframework.data.mongodb.core.index.IndexDefinition)' The calling method's class, org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration, was loaded from the following location: jar:file:/C:/Users/wbertolasi/.m2/repository/org/springframework/ai/spring-ai-autoconfigure-model-chat-memory-repository-mongodb/1.1.0/spring-ai-autoconfigure-model-chat-memory-repository-mongodb-1.1.0.jar!/org/springframework/ai/model/chat/memory/repository/mongo/autoconfigure/MongoChatMemoryIndexCreatorAutoConfiguration.class The called method's class, org.springframework.data.mongodb.core.index.IndexOperations, is available from the following locations: jar:file:/C:/Users/wbertolasi/.m2/repository/org/springframework/data/spring-data-mongodb/4.0.4/spring-data-mongodb-4.0.4.jar!/org/springframework/data/mongodb/core/index/IndexOperations.class The called method's class hierarchy was loaded from the following locations: org.springframework.data.mongodb.core.index.IndexOperations: file:/C:/Users/wbertolasi/.m2/repository/org/springframework/data/spring-data-mongodb/4.0.4/spring-data-mongodb-4.0.4.jar Action: Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.ai.model.chat.memory.repository.mongo.autoconfigure.MongoChatMemoryIndexCreatorAutoConfiguration and org.springframework.data.mongodb.core.index.IndexOperations

It seems there is no way starting the application with no errors.

Steps to reproduce ``` 1. Configure Spring Boot + Spring AI with the configuration above. 2. Start the application. 3. Observe the error.

Expected behavior When create-indices: true is set and ttl is defined, Spring AI should automatically create: 1. a TTL index (expireAfterSeconds = ttl) on the document creation date field (or equivalent) 2. any other necessary indices for managing the chat memory (e.g., on conversationId, createdAt, etc.) These indices should be visible in MongoDB via getIndexes().

Comment From: JGoP-L

Hi @ilayaperumalg,

I've investigated this issue thoroughly and have a complete fix ready. Could you please assign this issue to me?

Root Cause

Spring Data MongoDB changed its index creation API between versions: - 4.2.x - 4.4.x: Only ensureIndex(IndexDefinition) exists - 4.5.x and later: Introduced createIndex(IndexDefinition) and deprecated ensureIndex()

The current code hardcodes createIndex(), which doesn't exist in versions before 4.5.x, causing NoSuchMethodError when users run with Spring Boot 3.2.4 - 3.4.x (which include Spring Data MongoDB 4.2.x - 4.4.x).

I verified this by: 1. Inspecting the actual API in 4.2.4 and 4.3.4 via reflection - only ensureIndex() exists 2. Checking the source code on GitHub - createIndex() was introduced in 4.5.0

Proposed Fix

Use reflection with a fallback strategy to support both APIs:

  1. Extract index creation into a createIndexSafely() method
  2. Try createIndex() first (new API for 4.5.x+)
  3. Fall back to ensureIndex() if NoSuchMethodException occurs (for 4.2.x - 4.4.x)

private void createIndexSafely(IndexOperations indexOps, IndexDefinition index) { try { // Try new API (Spring Data MongoDB 4.5.x+) Method method = IndexOperations.class.getMethod("createIndex", IndexDefinition.class); method.invoke(indexOps, index); } catch (NoSuchMethodException ex) { // Fall back to old API (Spring Data MongoDB 4.2.x - 4.4.x) try { Method method = IndexOperations.class.getMethod("ensureIndex", IndexDefinition.class); method.invoke(indexOps, index); } catch (Exception ex2) { logger.error("Failed to create MongoDB index: {}", ex2.getMessage(), ex2); throw new RuntimeException("Failed to create MongoDB index", ex2); } } catch (Exception ex) { logger.error("Failed to create MongoDB index: {}", ex.getMessage(), ex); throw new RuntimeException("Failed to create MongoDB index", ex); } }## Testing

Successfully tested on multiple Spring Boot versions:

Spring Boot Spring Data MongoDB API Used Result
3.2.4 4.2.4 ensureIndex() ✅ Pass
3.3.4 4.3.4 ensureIndex() ✅ Pass
3.4.1 4.4.1 ensureIndex() ✅ Pass

I'm ready to submit a clean PR with the fix. Please let me know if you'd like me to proceed!

Thank you!

Comment From: deejay1

Spring AI 1.1.0 depends on Spring Boot 3.5.7, although now I notice that the docs state that Spring AI supports Spring Boot 3.4.x and 3.5.x. (https://docs.spring.io/spring-ai/reference/getting-started.html), so probably feel free to submit a PR as it's my fault. I definitely wouldn't support Spring Boot 3.2 if more changes are needed as OSS support ended last year with commercial support ending this year (as far as I know of course)