spring-data-mongodb. How can i dynamically create a database in mongo using spring-data-mongodb library? - mongodb

spring-data-mongodb. How can i dynamically create a database in mongo using spring-data-mongodb library?
I am trying to use Spring-Mongodb-Data module for CRUD operations against Mongo database and going through examples and articles my assumption is that databasename should be pre-defined in spring context xml when defining MongoTemplate bean.
In my case I have an multi-tenant application that will accept requests over http and my application should create the mongodatabase on-the-fly and use the name provided in the input http request to create the database and then load the data into collection in the newly created database.
I am trying to figure out if there is a way to dynamically populate the databasename in MongoTemplate or MongoRepository without having to provide it in spring context.xml?
Please help me.
Thanks
-RK

Have you tried the following instead of going through the pre-defined spring context configuration.
MongoTemplate getMongoTemplate(Mongo mongo, String database) {
return new MongoTemplate(mongo, database);
}

Related

Nested Query in spring batch processing

I want to create an ETL process using Spring Batch, the steps will be read from a DB(s) and insert in one DB so basically I'm collecting similar information from different DB and inserting them in one DB, I have a large complex query that I need to run on those DBs and the result will be inserted in the so called one DB for later processing, my main concert is that I want to reference this query in the JpaPagingItemReader for example, it there a way I can for example add this query in my project as .sql file and then reference it in the reader?
Or any other solution I can follow?
Thank you
it there a way I can for example add this query in my project as .sql file and then reference it in the reader? Or any other solution I can follow?
You can put your query in a properties file and inject in your reader, something like:
#Configuration
#EnableBatchProcessing
#PropertySource("classpath:application.properties")
public class MyJob {
#Bean
public JpaPagingItemReader itemReader(#Value("${query}") String query) {
return new JpaPagingItemReaderBuilder<>()
.queryString(query)
// set other reader properties
.build();
}
// ...
}
In this example, you should have a property query=your sql query in application.properties. This is actually the regular Spring property injection mechanism, nothing Spring Batch specific here.

How to ignore #Indexed annotation for Spring Data Mongo

I have multiple projects that use the same class User which has the following annotation:
#Indexed(direction=IndexDirection.DESCENDING)
private Date created = null;
I don't want each project to generate a call to mongo to create the index as this causes issues (e.g. if I want to change the index).
Is there a way to ask Spring Data Mongo to ignore the #Indexed annotation via the configuration file (or other way)?
The upcoming Spring Data MongoDB 2.2 allows to turn off annotated index creation via MongoConfigurationSupport#autoIndexCreation or directly by calling mongoMappingContext.setAutoIndexCreation(false).
Please see the reference documentation for 2.2.0.RC1 for more details.

One repository to two databases, MongoDB and Spring Boot

I have a repository which I want to save inside two different MongoDB databases, programmatically.
If the user enters an URL with the parameter DB1, the repository will save inside the database DB1, if it is DB2, to the database DB2, etc.
Is there any way to do this?
Not automatically. You need to have the application connected to 2 DBs and call each one depending on the parameter that comes in from the request. You'll need two separate repositories as far as I'm aware.
It is not possible to do with repositories easily (use multiple repositories with a little modification, because we can't use one, for each parameter in the URL is a madness.
So to avoid a lot of duplicate code we have to use the Java Driver.
MongoClient mongoClient = new MongoClient("localhost", 27017);
//here we can change the database name
MongoOperations mongoOperations = new MongoTemplate(mongoClient, database);
mongoOperations.save(YOUR_POJO);
mongoClient.close();
The POJO object has to use de #Documentannotation, if not you will have codec problems. Here you can solve them: http://mongodb.github.io/mongo-java-driver/3.2/bson/codecs/

How to dynamically create MongoTemplate instances, with credentials?

Prior to Spring Data MongoDB 1.9.0-RELEASE, I was able to create a MongoTemplate object as follows:
new MongoTemplate(client, dbName, credentials). Upon upgrading, this constructor no longer works, giving an error to use MongoCredential instead. However, there is no similar MongoTemplate constructor that uses MongoCredential. It appears that the only way to specify credentials now is when constructing the MongoClient object.
However, since my app is multitenant on the database level, this doesn't work because it does not allow for additional credentials to be added after construction (meaning MongoTemplates cannot be created dynamically). It also is not ideal because if any of the credentials in the list are bad, none of the database connections work, as opposed to just the one with bad credentials.
I also do not want to create a new MongoClient instance for each database. From what I understand, doing so would create a new connection for each database rather than letting MongoClient manage a connection pool, which is ultimately not sustainable since Mongo only allows a finite number of connections.
Do I have any options here besides continuing to use the outdated library?
What you can do is instantiate the MongoClient and cache it using a HashMap with some unique db identifier as key and mongoClient as value. Use that create MongoTemplate
What I ended up doing is creating a single user in the admin database that has access to all of the databases that I need (achieved via the roles array). I create one MongoClient, authorizing as that user against the admin database. Then I am able to create MongoTemplate objects dynamically without issue, because the user I'm authorized as hasreadWrite permissions on those databases.

Spring Data Crate custom queries

I am trying to implement Spring Data Crate API in a project. Following the instructions provided here:
https://crate.io/a/using-sprint-data-crate-with-your-java-rest-application/
Inserts/Updates/FindById methods are covered. My question is how to create custom queries using this API.
Have you looked at our Spring Data adapter?
Declared Queries
It's also possible to use the #Query annotation to define queries:
public interface UserRepository extends CrateRepository<User, String> {
#Query("select * from users")
List<User> getAllUsers();
}
https://github.com/crate/spring-data-crate#declared-queries
please note that the crate java-client is not supported anymore since v0.57 unfortunately.
https://crate.io/docs/clients/java/
This leaves us with the java-jdbc:
https://github.com/crate/crate-sample-apps/blob/master/java/documentation.md
Spring data adapter is using the java-client.
Here is a Spring Boot application that is using JDBC in order to access CrateDB (> v0.57.0) https://github.com/klearchos/crate
And here are the official samples in order to access CreateDB through JDBC (using the Spark framework). https://github.com/crate/crate-sample-apps/tree/master/java