Spring boot with mongodb and redis as cache

Viewed 157

I have a spring boot project, where i use mongodb as my main database, I wanted to include redis as a cache for the project, because it has many image accesses and it would be pretty heavy for the main db.

<dependencies>  
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>   
        <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.google.firebase</groupId>
        <artifactId>firebase-admin</artifactId>
        <version>8.1.0</version>
    </dependency>
    <!-- Exclude tomcat dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Include jetty dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
</dependencies>

that are my current dependencies

whenever I want to add:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

i get this error:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.mapping.context.MappingContext' available: expected single matching bean but found 2: mongoMappingContext,keyValueMappingContext

does anyone have a idea how to fix this?

1 Answers

I run into exact same issue recently. You didn't mention what is your version of Spring Boot, but this got me while upgrading from 2.6.6 to 3.0.0-M3. Same code works fine with older version, so I started digging...

Long story short, the root cause is in MongoAuditingRegistrar, so I guess you're using @EnableMongoAuditing annotation. When I disable auditing, everything works fine also with 3.0.0-M3 version.

The culprit is here:

definition.addConstructorArgValue(new RuntimeBeanReference(MappingContext.class));

In case you are using both Mongo and Redis, there are two mapping contexts available and Spring doesn't know which one to use, as reference by MappingContext interface is too generic.

In version 2.6.6 the same thing was done like this:

definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);

The quick and dirty, probably not the best and final, solution that worked for me was to create my own @EnableCustomMongoAuditing annotation which instead of:

@Import(MongoAuditingRegistrar.class)

would use:

@Import(CustomMongoAuditingRegistrar.class)

with the small change of above mentioned line to:

definition.addConstructorArgValue(new RuntimeBeanReference(MongoMappingContext.class));

I hope it can work, even if as a temporary solution, for you too.

Related