How to connect to MongoDB 3.0 using Spring Boot

My problem

Yesterday, I spent more than 5 hours trying to fix a compatibility issue between the latest version of spring-boot (1.2.6.RELEASE) and a mongoDb 3.0 database.

My problem was that I was using a free MongoDB-as-a-Service and they decided to upgrade from version 2.X to 3.0. As a result, my jhipster application could not connected to the database, and all that I could see in the logs were:

Caused by: com.mongodb.CommandFailureException: { “serverUsed” : “xxx” , “ok” : 0.0 , “errmsg” : “auth failed” , “code” : 18}

The solution

After a lot of reading, I finally manage to found what was the problem: “MongoDB 3.0 changed the default authentication mechanism from MONGODB-CR to SCRAM-SHA-1”.

In order to solve this problem, I followed these 3 steps:

  • Update to the latest version of Spring Data Mongodb
  • Add the latest version of the mongo-java-driver
  • Set MongoClient specific options for setting credentials

1) Update to the latest version of Spring Data Mongodb

My problem was that the latest version of spring-boot-starter-data-mongodb(1.2.6.RELEASE) was using by default an older version of Spring Data MongoDB. In order to use the latest version of Spring Data MongoDB, the easiest way to update it is by setting the spring-data-releasetrain.version property in their Maven POMs to Fowler-SR2.

And here it is an snippet of my pom.xml:

...
<parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>1.2.6.RELEASE</version>
        <relativePath />
</parent>
<properties>
      ...
    <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
<dependencies>
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
   </dependency>

...

2) Add the latest version of the mongo-java-driver

Once you are using the latest version of Spring Data MongoDB, you will need to update the mongo java driver to the latest version, so I have added this bit to my pom.xml:

<dependencies>
...
<dependency>
       <groupId>org.mongodb</groupId>
       <artifactId>mongo-java-driver</artifactId>
       <version>3.0.4</version>
</dependency>

...

3) Set MongoClient specific options for setting credentials

According to the Spring Data MongoDB Documentation “MongoDB Server generation 3 changed the authentication model when connecting to the DB. Therefore some of the configuration options available for authentication are no longer valid. Please use the MongoClient specific options for setting credentials via MongoCredential to provide authentication data.”

So you will need to set your credential using MongoCredential.createCredential method. Please have a look to this database configuration example:

@Configuration
@EnableMongoRepositories("your_package_repositoy_name")
@EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class DatabaseConfiguration extends AbstractMongoConfiguration {

    private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);


    @Value("${spring.data.mongodb.host}")
    private String host;

    @Value("${spring.data.mongodb.port}")
    private Integer port;

    @Value("${spring.data.mongodb.username}")
    private String username;

    @Value("${spring.data.mongodb.database}")
    private String database;

    @Value("${spring.data.mongodb.password}")
    private String password;

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() {
        return new ValidatingMongoEventListener(validator());
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }
    

    @Override
    public String getDatabaseName() {
        return database;
    }

    @Override
    @Bean
    public Mongo mongo() throws Exception {

        return new MongoClient(singletonList(new ServerAddress(host, port)),
                singletonList(MongoCredential.createCredential(username,database, password.toCharArray())));
    }

}

I hope this post help you solve your problem and you don’t waste as much time as I did. Please any comments or queries let me know.

You may also like...

11 Responses

  1. Rich says:

    Thanks for this.

    I had the same error with a Spring Boot app using a new Mongo 3.0 database. By upgrading to the latest version of the Java Mongo driver (3.0.4) and then adding the authentication mechanism param to the URI in my application.properties, I was able to get it working:

    spring.data.mongodb.uri=mongodb://myusername:mypassword@localhost/?authSource=admin&authMechanism=SCRAM-SHA-1
    spring.data.mongodb.database=test

    Thanks!

    Rich

  2. johnny says:

    Cool that worked really well.
    But I had to remove @EnableMongoAuditing(auditorAwareRef = “springSecurityAuditorAware”), as it caused errors.
    Thanks a lot for this post! It made my day.

  3. Benjamin says:

    Thanks for help !

  4. Danny Suarez says:

    Thank so much man!!!! Finally I got it…you save my life…
    I share you my solution…

    List servers=new ArrayList();
    servers.add(new ServerAddress(“xxxxxxxxx”, portnumber));

    List creds=new ArrayList();
    creds.add(MongoCredential.createCredential(“yyy,”databaseName”, “XXXXXXX”.toCharArray()));
    return new MongoClient(servers,
    creds);

  5. chunku babu says:

    really good post man

  6. Manuel Garcia says:

    It works fine on springBoot 1.3.2 ! Thanks

  7. Rob says:

    Thanks a lot!

  8. Marc R says:

    Ignacio, thank you for this post!

Leave a Reply

Your email address will not be published. Required fields are marked *