Spring Data Mongo - Dynamically change repository template - java

I have this scenario: same database structure (same collections) replicated in multiple mongo databases. This mean that I have one mongo repository for each collection (Document).
Now I need to manage these databases through the same Control Panel App, connecting to each one of them dynamically, and using the same repository classes (the databases are identical).
I know that I can specify known templates for repositories as described in this post, but this implies that I have to know the database's connection properties at startup. How can I implement a dynamic behaviour of that, instead?

The core interface you might want to look at is MongoDBFactory. You can provide a custom one by overriding mongoDbFactory() in AbstractMongoConfiguration or just an ordinary bean definition in XML.
To transparently switch between different databases, simply keep track of the one selected in the implementation and return a DB instance according to that.

Related

Connecting to different database dynamically in java springs

I have created the Databse dropdown list using the JSP. If I select anyone of the database and it should be pointing to the database and then the query written should be executed to the database which I have selected.
Present work done.
Now I have created statically like how much database I have that much Properties are written in the property file and all the credentials will be taken by Context.xml so how can i create it dynamically so that I dont want to write the different properties for each database and i dont want to create the different session nor I don't want to restart the server when ever I select the DataBase ?
In the property file I have written the different properties for each and every databases and in XML also we have created the different sessions for each and every databases so i donit need to write the different sessions nor restart my Server after the selection of the Database
My question is to can we implement as per my requirement.??????
And another thing for the different database we have created the interface and for that interface we have created the implementation
I believe there is nothing prohibit you from programmatically creating all DB related artifacts (e.g. Datasource, JdbcTemplate, EntityManager etc), and perform transaction management programmatically. Of course you will be giving up a lot of facilities provided by the container (or, I should say, still achievable with high cost)
Another idea I believe will work (though I haven't tried) is to create a child application context from your main app context. The child context will prepare/lookup datasource etc base on properties. Your parent context will of course need to provide correct properties to the child context. By doing so, it should be easy to leverage on feature provided by Spring.

Switching between databases Spring MongoDb

I have a case, where I need to switch between the mongo databases using Spring mongodata (Version: 1.6.2). Currently, I have default database configured in db-config.xml with mongo template, and have annotated repositories; Need is to switch from one db/template to another at runtime; do necessary actions and switch back to default one.
I referred to couple of links,
Spring-data-mongodb connect to multiple databases in one Mongo instance
and
Making spring-data-mongodb multi-tenant
I need to use same set of repositories at runtime. Is it possible to handle my case at configuration level? or do we need to extend Dbfactory to achieve this?
with Dbfactory, can I use same set of annotated repositories?
Appreciate any help.
You can extend:
1. `SimpleMongoDbFactory`: returning custom DB in DB `getDb(String dbName)`.
2. `MongoTemplate`: Supplying above factory.
Use appropriate MongoTemplate with the help of #Qualifier.
I once had a very similar problem.
I published the code on github, check it out multi-tenant-spring-mongodb
You basically have to extend SimpleMongoDbFactory and handle other hosts too. I just did handle multiple databases on the same server. That shouldn't be a problem.

How to use Spring to mange mulitple "runtime noticed" database connection with different jdbc(or hibernate?)?

I have a web application access to a database which it's connection info(connection string,username,pwd) are enter by the user at runtime.
thus, I can not notice any information in deploy time.
The system is supposed to support multiple type of database with different jdbc
How can I manage this situation using spring/hibernate(I doubt that hibernate can handle this because the data structure is known in runtime)??
You can use an approach similar to the one described here
Basically just subclass AbstractRoutingDataSource and override the method determineTargetDataSource (if you need to create the datasources from within your application) or determineCurrentLookupKey (if your datasources are going to be already created in the app server).
In the determineTargetDataSource method you can return whatever datasource you need, or create a new one if need be.

Connecting two datasources to the same database

I am working on an application where we have decided to go for a multi-tenant architecture using the solution provided by Spring, so we route the data to each datasource depending on the value of a parameter. Let's say this parameter is a number from 1 to 10, depending on our clients id.
However, this requires altering the application-context each time we add a new datasource, so to start we have thought on the following solution:
Start with 10 datasources (or more) pointing to different IPs and the same schema, but in the end all routed to the same physical database. No matter the datasource we use, the data will be sent to the same schema in this first scenario.
The data would be in the same schema, so the same table would be shared among datasources, but each row would only be visible to each datasource (using a fixed where clause in every CRUD operation)
When we have performance problems, we will create another database, migrate some clients to the new schema, and reroute the IP of one of the datasources to the new database, so this new database gets part of the load of the old one
Are there any drawbacks with this approach? I am concerned about:
ACID properties lost
Problems with hibernate sessionFactory and second level cache
Table locking issues
We are using Spring 3.1, Hibernate 4.1 and MySQL 5.5
i think your spring-link is a little outdated, hibernate 4 can handle multi-tenancy pretty well on it's own. i would suggest to use the multiple schemas approach because setting up and initializing a new schema is programmatically relativly easy to do (for example on registration-time), if you have so much load though (and your database-vendor does not provide a solution to make this transparent to your application) you need the multiple database approach, you should try to incorporate the tenant-id in the database-url or something in that case http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html

Pattern for connecting to different databases using JDBC

I'm writing an application which has to be configurable to connect to Oracle, SQL Server and MySQL depending on client whim.
Up till now I'd been planning on using the JDBC-ODBC bridge and just connecting to the databases using different connection strings.
I'm told this is not very efficient.
Is there a pattern or best practice for connecting to multiple database systems? Or for selecting which driver to use?
Should I have it configurable? but include all three drivers or build three separate clients?
I'm not doing anything complex just pumping (inserting) data into the database from an event stream.
I would suggest that you make it configurable and include the three drivers. You can use a pattern like this: Create a super class (lets call it DAO) that provides the functionality of connecting to the database. This could be abstract.
Create a concrete sub class for each type of database that you wish to connect to. So you may end up with MySQLDAO, MSSQLDAO, and OracleDAO. each one will load the respective driver and use its respective connection string.
Create another class (lets call it DAOFactory) with a method getDAO(DB) that will create an instance of the DAO depending on the value of DB.
So for instance(in Pseudocode):
if(DB.equals("MySQL")){
DAO = new MySQLDAO();
}
return DAO;
So any code that needs to connect to the database will call the DAOFactory and ask for a DAO instance. You may store the DB value in an external file (like a properties file) so that you do not have to modify code to change the type of database.
this way your code does not need to know which type of database it is connecting to, and if you decide to support a fourth type of database later you will have to add one more class and modify the DAOFactory, not the rest of your code.
If you need anything complex, Hibernate is a good choice.
otherwise, what I would do is store your connection details in a properties file (or some other form of configuration) - namely: driver classname, JDBC url, username and password.
Then, all you need to do is load up the connection details from your properties file and include the correct JAR file on your classpath and you're done.
You could use a library such as Commons-DBCP if you wanted it to be a little easier to configure but other than that it's all you need to do (provided your SQL statements work on every database, of course).
If you're careful (and you test), you can do this with straight JDBC and just vary the driver class and connection information. You definitely want to stay away from the JDBC-ODBC bridge as it's generally slow and unreliable. The bridge is more likely to behave differently across dbs than JDBC is.
I think the DAO path is overkill if your requirements are as simple as listed.
If you're doing a lot of inserts, you might want to investigate prepared statements and batched updates as they are far more efficient. This might end up being less portable - hard to say without testing.
Take a look at Datasource. This is the preferred mechanism for obtaining a database connection.
IMO this provides an adminstrator the greatest flexibility for choosing database, connection pooling, and transaction strategies.
If you're using tomcat, then see here for how to register a Datasource with tomcat's JNDI.
If you're using Spring, then you can obtain a Datasource using jee:jndi-lookup.
If you're using Spring, but don't want to use JNDI, take a look at DriverManagerDataSource for a discussion of how to obtain a pooled Datasource (DBCP or C3P0).

Categories