Mongo DB multi tenancy with CodecRegistry

Working on multi tenant spring boot application.
Where I m trying to connect to multiple database at runtime based on tenant id.

I created mongoclient with application name then service class provides db instance at runtime.

class MultiTenantMongoDbService {
private final ConcurrentMap<String, MongoDatabase> mongoDbFactories = new ConcurrentHashMap<>();
private MongoClient mongoClient;

@Autowired
public MultiTenantMongoDbService(MongoClient mongoClient){
this.mongoClient = mongoClient;
}

public MongoDatabase getDb() {
String tenantId = TenantContext.getCurrentTenant();
if(mongoDbFactories.containsKey(tenantId)){
return mongoDbFactories.get(tenantId);
}
mongoDbFactories.put(tenantId, getMongoDatabase(tenantId));
return mongoDbFactories.get(tenantId);
}

private MongoDatabase getMongoDatabase(String dbName){
return this.mongoClient.getDatabase(dbName);
}
}
inside dao classes i always call getDb().getCollection(“users”).find() Is it the good approach ?

In this approach i cannot apply codec registry at runtime ? because in the examples mongo collection is created at bean initialization.

Hi @Karesh_Arunakirinathan,

I am trying to understand the situation, so help me out if I misunderstood anywhere. Your application needs a runtime db name depending on the tenantId (what is in your hashmap)

Now, I like what you did using hashmap and then creating db object. Writing this in a function to avoid repetition of code.

I have one concern here:

This one, calling getDb() again and again would result into various database handles in a single run of application. Now, if your tenantId is supposed to change multiple times in a single run that means different for every DAO class then it makes sense. But if it is one per application (run) and only needs to be decided once, then you can create a Singleton class and create an object of database handle there and then use that db object everywhere else in your application.
Does that makes sense? :slight_smile: Again, this is just my opinion and understanding. I might be wrong here and other users can help you out better.

If you would like you can create a post in our community forums: https://developer.mongodb.com/community/forums/

Kanika

In spring boot- every request is new thread. I add tenant id inside threadlocal and used it in getDB.
I can create many db on startups but when new tenant onboarded to system. we need to restart all our services. That is not a good design.
So I decided keep the the db objects in map, if second request comes from same tenant it get the db object from map.(wont create new one per request).

eg:
tenant 1 -> db name : tenantone
tenant 2 - > db name: tenanttwo.

We create multiple database inside one atlas mongo cluster. Hope this clear