Search code examples
javamongodbconnection-poolingconnection-pool

MongoDb with java : create new connection pool and destroy the previous one


I am implementing mongodb in java. Whenever my application starts new connection pool for mongoDB is created. Is there any way I can destroy that connection pool and create a new one, without restarting my application. I know that if any argument is change in mongoURI, a connection pool is reinitialized, but I want to know if there is anyway we can do that without making any changes in URI arguments.By main goal is to destroy the connection pool and create new connection pool ! This connection pool is created by MongoClient bean. Therefore I wanted to destroy and recreate the MongoClient Bean.

<bean id="monURI" class="com.mongodb.MongoClientURI"> <constructor-arg name="uri" value="${MONGO_URI}"/> </bean>

<bean id="mongoC" class="com.mongodb.MongoClient"> <constructor-arg ref="monURI"/> </bean>


Solution

  • Is it possible for you to share some code so we can be more helpful to your specific situation?

    Where I work, we are using com.mongodb.MongoClient. If you are using it as well you can make a call to mongoClient.close() before destroying the connection manger component (working with Spring, so we call the close() in the @PreDestroy method of the component)

    ------- EDIT -------

    Following our comments on this answer I would go with either of these approaches:

    1. Wrap the MongoClient with a class of your own that holds a MongoClient instance. This class will expose a method (let's call it resetConnectionPool), and inside that method you will call mongoClient.close() and mongoClient = new MongoClient().
      You might have to @Autowire the MongoClientURI bean to use it inside the class you create. Something along the line of this class:

    ;

    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import java.net.UnknownHostException;
    
    @Component
    public class MongoClientWrapper {
        @Autowired
        private MongoClientURI mongoClientURI;
    
        private MongoClient mongoClient;
    
        @PostConstruct
        public void init() {
            mongoClient = getNewMongoClientInstance();
        }
    
        @PreDestroy
        public void beforeTearDown() {
            mongoClient.close();
        }
    
        public void resetConnectionPool() {
            mongoClient.close();
            mongoClient = getNewMongoClientInstance();
        }
    
        private MongoClient getNewMongoClientInstance() {
            MongoClient client = null;
            try {
                client = new MongoClient(mongoClientURI.getURI());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } finally {
                return client;
            }
        }
    }
    
    1. Reconsider the scope of the MongoClient bean. Maybe instead of singleton it should be per request or per http session? Have a look at these links for more on bean scopes:
    2. According to this javadoc: https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClientURI.html you can add options to the URI. You can add an option that no one uses but contains the current timestamp. If you want to reset the pool, change only that timestamp, and that "changes" the URI and thus resets your connection pool. Something along the line of:
      mongodb://[username:password@]host1:port1/dbName?_=1534228866003

    ----- END EDIT -----