tags:

views:

809

answers:

6

Usually when defining a DAO, you would have a setter for the datasource on the DAO object. My problem is that our datasource varies dynamically based on the request to the server. i.e. every request can access different database instance.

The request holds logical properties, that later can be used to retrieve the connection to the DB of the request.

So when dependency injecting the DAO to the business logic object, I need a way to set the properties on the DAO at runtime (not configuration time).

One solution is to store the datasource on the thread local, but I don't really like messing with thread local variables.

Another option is to have an initialize method on the business logic object that calls initialize on the DAO with the request properties.

I guess it's a common problem, can you suggest a common solution?

+5  A: 

Your problem is a little confusing. Having one DAO access multiple different datasources would seem to be a maintenance nightmare. As a result, you should define one DAO interface containing all the methods you would want to call. For each database you are connecting to I would construct a new class that implements your DAO interface. This allows you to have multiple implementations. I would then store these implementations (each that has its own datasource) in a Map (java.util.Map), using your "logical properties" as the key to the map. Since all your DAO Implementations implement your interface you will be able to cast them to the interface and use them interchangeably. On your business object, you would inject the Map of DAO implementations. I hope this helps your design.

Nick
+5  A: 

It sounds like your problem is that you are creating a single DAO instance for your application. You either need to create a separate instance for each datasource (maybe making some kind of dao controller to manage it all for you) or possibly allow your methods in your dao to be static and pass all information about how to connect to the datasource along with the data you are persisting into every method.

Ryan Guill
Sensible answer.
James P.
+4  A: 

I had such a problem on a client/server project. Client and Server projects was sharing Dao interfaces. And When I used to do database operation I had to select suitable Dao implementation. My solution was like this :

IVehicleDao vehicleDao =daoFactory.Get<IVehicleDao>(parameters);
vehicleDao.doSomething();

Get dao from Factory by passing parameters.Inside Dao factory decide which Dao implementation to return..

mcaaltuntas
+2  A: 

You may want to look into this class:

http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

This will make it easier for your service objects and data access objects to be ignorant that any notion of dynamic datasources exists.

Typically you'd need to implement a servlet filter and use a ThreadLocal so that the DataSourceLookup implementation used by AbstractRoutingDataSource can easily gain access to the request parameters that dictate which DataSource is returned. If you really want to avoid that, you could implement a servlet filter which sets properties on a request-scoped bean and inject that bean into the DataSourceLookup implementation you've written. Request-scoped beans still use a ThreadLocal in their implementation but at least this way it's Spring's impl, not yours, and you don't need to worry about it. :)

Similar approach is detailed in this blog entry from the Spring team:

http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

cliff.meyers
A: 

Hi, i have the asme problem, please could you explain how can i get access to the request from DataSourceLookup or AbstractRoutingDataSource??? i read the post: http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/ but i cant understand how to get access to the parameters in the request, please help me...

A: 

Hi, guy.

I already did this. You need to create one DAO each class, and in the scope of your DAO you need to pass the DATASOURCE and finally one class CONTROLLER where you do dynamic calling to DAO.

It's simple.

Regards, Luis Garcia - BR.

Luis Garcia