I am using the latest spring-data-mongodb (1.1.0.M2) and the latest Mongo Driver (2.9.0-RC1). I have a situation where I have multiple clients connecting to my application and I want to give each one their own “schema/database” in the same Mongo server. This is not a very difficult task to achieve if I was using the driver directly:
Mongo mongo = new Mongo( new DBAddress( "localhost", 127017 ) );
DB client1DB = mongo.getDB( "client1" );
DBCollection client1TTestCollection = client1DB.getCollection( "test" );
long client1TestCollectionCount = client1TTestCollection.count();
DB client2DB = mongo.getDB( "client2" );
DBCollection client2TTestCollection = client2DB.getCollection( "test" );
long client2TestCollectionCount = client2TTestCollection.count();
See, easy. But spring-data-mongodb does not allow an easy way to use multiple databases. The preferred way of setting up a connection to Mongo is to extend the AbstractMongoConfiguration class:
You will see that you override the following method:
getDatabaseName()
So it forces you to use one database name. The repository interfaces that you then build use that database name inside the MongoTemplate that is passed into the SimpleMongoRepository class.
Where on earth would I stick multiple database names? I have to make multiple database names, multiple MongoTempates (one per database name), and multiple other config classes. And that still doesn’t get my repository interfaces to use the correct template. If anyone has tried such a thing let me know. If I figure it out I will post the answer here.
Thanks.
So after much research and experimentation, I have concluded that this is not yet possibly with the current
spring-data-mongodbproject. I tried baja’s method above and ran into a specific hurdle. TheMongoTemplateruns itsensureIndexes()method from within its constructor. This method calls out the the database to make sure annotated indexes exist in the database. The constructor forMongoTemplategets called whenSpringstarts up so I never even have a chance to set aThreadLocalvariable. I have to have a default already set whenSpringstarts, then change it when a request comes in. This is not allowable because I don’t want nor do I have a default database.All was not lost though. Our original plan was to have each client running on its own application server, pointed at its own
MongoDBdatabase on theMongoDBserver. Then we can provide a-Dprovider=system variable and each server runs pointing only to one database.We were instructed to have a multi-tenant application, hence the attempt at the
ThreadLocalvariable. But since it did not work, we were able to run the application the way we had originally designed.I believe there is a way though to make this all work, it just takes more than is described in the other posts. You have to make your own
RepositoryFactoryBean. Here is the example from the Spring Data MongoDB Reference Docs. You would still have to implement your ownMongoTemplateand delay or remove theensureIndexes()call. But you would have to rewrite a few classes to make sure yourMongoTemplateis called instead ofSpring's. In other words, a lot of work. Work that I would like to see happen or even do, I just did not have the time.Thanks for the responses.