lookup datasource in context every time, Is it right? - java

In my application i configured more than one datasource (for diff databases). Whenever user sends a request depends upon user category i need to look up for the respective datasource in the context and get a connection from that datasource to execute queries which are assigned to that user. Is it right way to achieve my requirement? I am using tomcat 6, struts 1.3. The databases may be oracle or mysql or both.
Give me an optimized solution.
Thanks in advance.

Alternatively, you can create a Service Locator where you can cache every JNDI objects retrieved. That way, you don't have to invoke the JNDI lookup every time but pull out from the cache.

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.

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

How to set default schema in a Spring/mybatis application with Oracle DB?

Coming from a mysql background, I am able to set the default schema name that I want to use for all my sql queries in the connection url. I now have an Oracle DB that I need to access. I am aware that I cannot specify the schema I want to use in the URL since the user is the schema name being used.
I realize that I can use a line of SQL code:
ALTER SESSION SET CURRENT_SCHEMA=default_schema
The project is using mybatis 2.3.5 as my SQL framework, but I am completely new to mybatis. Is there a simple way to configure mybatis to accomplish this? My application is a Spring 3 application, so I am using the Spring DataSourceTransactionManager to manage my transactions. I would presume that the manager must be made aware of this requirement to ensure that the command is sent whenever creating a new connection.
I've tried searching online, but most of the examples I find all have the schema names included within the sql queries in the SqlMaps, which I find to be bad practice.
In an ideal world, the schema name would be part of the URL such that I can make changes to the schema name for different environments (ex: dev, test, prod, etc) without touching the code (ie: only configured at the JNDI/application server level). I would be happy if I could use a Spring configuration value to set this as well as I could still use a JNDI lookup or a system environment property to retrieve the value.
Can anyone point me in the right direction?
Thanks,
Eric
As far as I know, there is no option in Oracle to change your URL in order to connect to a specific user schema.
1) mybatis: You may set your current schema to a deserved one before you start your operations. You can write your specification in a property file and set your method's arguments from that file. You do not need to change your code to change your schema in that case.
<update id="mySetSchemaMethod" parameterClass="String">
ALTER SESSION SET CURRENT_SCHEMA = ${schemaName}
</update>
2) trigger: If you are using this connection only for this particular java application, you can set a client event trigger so set your CURRENT_SCHEMA. This time, you need to change the trigger in order to manage test/prod changes.
CREATE OR REPLACE TRIGGER Set_Schema_On_Logon
AFTER LOGON
ON MY_SCHEMA
BEGIN
ALTER SESSION SET CURRENT_SCHEMA = MY_TEST_SCHEMA;
END;

Hibernate database password at runtime

Is there a way to ask for the database password at runtime instead of putting it (encrypted or not) in the hibernate.cfg.xml file?
Just about every configuration option in Hibernate has a corresponding method on the object being configured. In reality, the configuration is really just a way to bind XML to the objects being set up. See this article for more information: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html
That said, the onus is on you to collect the password at startup. That can be the most difficult part of the problem. Once you've collected the password, send it to the appropriate property.
Usually the best way to do it, if you're using a Java EE app server, is to use a JNDI look up to get the database connection instead of using a driver manager. That way the person who sets up the JNDI connection pool is the only one that has to know the password, and it's generally encrypted in the admin console so it's safe.
I think if you are using programmatic instantiation of the Hibernate configuration, you can initialize it from the configuration file that does not contain a password, set the additional property for the database connection on the configuration object you're instantiating, then call buildConfguration().

Multi-user Datasources - Spring + Hibernate

I'm writing a web app that supports multiple users. Each user has their own database - using H2. all database schemas are the same.
I wish to use Spring + Hibernate for this application.
So I'm stuck at how to associate a user's database with that user - maybe associated it in the HTTPSession, and extend spring's AbstractRoutingDataSource? but wouldn't this effect Hibernate's cache? Another way is to have a SessionFactory with each datasource, even though every datasource's schema is the same... so I see that as a waste.
Anyways selecting the datasource needs to be dynamic - they can't be pre-configured in context files, as each new user will have its own database created. Is there any existing frameworks/solutions?
I don't know too much about Hibernate Shards, maybe that works?
I might be wrong about the (strict) need to have one SessionFactory per database, as suggested by some resources:
Dynamic DataSource Routing
I'll take some time to re-read everything tomorrow (I didn't get all the details to be honest) and to fully understand the implications of such a setup (although it seems clear that it will break the second-level cache). I'll come back on this later.
I'm writing a web app that supports multiple users. Each user has their own database - using H2. all database schemas are the same.
I wonder how this will scale... How many users do you have? How do you run H2, what mode?
So I'm stuck at how to associate a user's database with that user - maybe associated it in the HTTPSession, and extend spring's AbstractRoutingDataSource?
You'll have to build a SessionFactory per user and associate it to the logged user (in a Map, using the login as key) and then obtain a Session from a given SessionFactory. Binding the lifecycle of the SessionFactory to the HTTP session seems to be a good idea (to save some memory) but I am not sure Spring will be very helpful here. I might be wrong but a variation of the HibernateUtil class and a fully programmatic approach looks easier. I'm not sure you'll need multiple connections per user by the way.
but wouldn't this effect Hibernate's cache?
What cache?
Another way is to have a SessionFactory with each datasource, even though every datasource's schema is the same... so I see that as a waste.
Oh, it's a waste, but that's what you want to do (one database per user). And you don't have the choice (you need one SessionFactory per datadabase). Why do you need one database per user actually? Are you sure this is a wise decision? As already hinted, this means much troubles, won't scale well, adds complexity, etc. Why not using a single database and associating data to the user?
Anyways selecting the datasource needs to be dynamic - they can't be pre-configured in context files, as each new user will have its own database created. Is there any existing frameworks/solutions?
Not to my knowledge. Which is also why I think you'll have to do everything programatically.
I don't know too much about Hibernate Shards, maybe that works?
Given the dynamic needs of your application, I don't see how it could help.
This may help you:
Dynamic Datasource via Spring using HotSwappableTargetSource
Hibernate + Spring using multiple datasources?
Thanks to the help from the 2 people (Pascal and org.life.java)!
It is possible, but with some problems: e.g. the hibernate 2nd level cache/query cache.
This link supplied by Pascal is a very good resource:
http://www.jroller.com/kenwdelong/entry/horizontal_database_partitioning_with_spring.
My main motivation for giving each user a separate database is because the data is likely to grow rapidly, thus horizontal partitioning is required.

Categories