You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-java@ibatis.apache.org by Fearghal O Maolcatha <fe...@gmail.com> on 2008/01/15 16:57:52 UTC

Changing datasource at runtime

Hi,

Our project is currently using Ibatis and the Ibatis DAOs. We plan to
migrate the Ibatis DAOs to Spring DAOs, which seems straightforward enough.
However we have a new requirement that will necessitate the changing of the
datasource at runtime. Our application has the notion of projects, with each
new project created by the user requiring a new database (same DB schema for
all projects). Any new work within the project will be saved to the newly
created database. The user can close a project and open an existing one,
which would require the datasource to be changed. I've had a look at a
previous thread
http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.html which
addresses a similar issue but the suggested implementation (wrapping the
datasource being injected into the SqlMapClient) would have implications for
the Ibatis cache from what I've read previously. We currently don't use the
Ibatis cache but might have to for performance reasons in the future.

Any suggestions on how to proceed with this would be welcome.

Regards,
Fearghal.

Re: Changing datasource at runtime

Posted by Fearghal O Maolcatha <fe...@gmail.com>.
Thanks for the feedback - creating a new Spring context could be a good
option as well.

On 16/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>
> OK - got it.
>
> So I think that'll work.
>
> You could also create a new Spring context when the DS changes and not do
> the routing.
>
> Or if you don't need caching, then you could just change the DS and use a
> single sqlmapclient.
>
> On 1/15/08 2:25 PM, "Fearghal O Maolcatha" <fe...@gmail.com>
> wrote:
>
> > My logic (flawed as it might be) was that I needed a wrapper for the
> > SqlMapClient. Each DAO would be injected with a wrapper
> > (RoutingSqlMapClient) for a SqlMapClient. When the datasource changes, I
> > construct a new SqlMapClient and update the reference in
> RoutingSqlMapClient
> > with the new SqlMapClient. The DAO is unaware of any changes to the
> > underlying datasource.
> >
> >
> > On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
> >>
> >> I'm confused - why do you need the routing if you only need to support
> >> access to one db at a time?
> >>
> >> On 1/15/08 10:41 AM, "Fearghal O Maolcatha" <
> fearghal.omaolcatha@gmail.com
> >>>
> >> wrote:
> >>
> >>> Hi Chris,
> >>>
> >>> Thanks for the response. I'd actually seen your solution previously. I
> >> was
> >>> using it as a starting point for what I was trying to do, specifically
> >> the
> >>> RoutingSqlMapClient class. I've modified it slightly for my purposes
> to
> >> just
> >>> contain a reference to one SqlMapClient. We only need to support
> access
> >> to
> >>> one database at a time.The bean 'projSqlMapClient' is injected with a
> >> known
> >>> database at startup. I've included some test code, where I construct a
> >> new
> >>> DataSource and update the projSqlMapClient bean with the newly
> >> constructed
> >>> SqlMapClient. It seems to work for the simple test case I've written
> but
> >>> there might be something I've overlooked. I'd appreciate any feedback
> >> you
> >>> might have on this approach.
> >>>
> >>> Thanks,
> >>> Fearghal.
> >>>
> >>>
> >>>
> >>> public class TestSpringContext {
> >>>
> >>>     public static void main(String[] args) throws Exception {
> >>>         ContextManager.getContext();
> >>>
> >>>         // Create DataSource for the new database
> >>>         BasicDataSource projectDS = new BasicDataSource();
> >>>         projectDS.setPassword("NsdSa123");
> >>>         projectDS.setDriverClassName("
> >>> com.microsoft.sqlserver.jdbc.SQLServerDriver");
> >>>         projectDS.setUrl
> >>> ("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
> >>>         projectDS.setUsername("Sa");
> >>>
> >>>         // Create a SqlMapClient for the new DataSource
> >>>         SqlMapClientFactoryBean factoryBean = new
> >> SqlMapClientFactoryBean();
> >>>         Resource resource = new ClassPathResource("config/sqlmaps/sql-
> >>> map-config.xml");
> >>>         factoryBean.setConfigLocation(resource);
> >>>         factoryBean.setDataSource(projectDS);
> >>>         try {
> >>>             factoryBean.afterPropertiesSet();
> >>>         } catch (Exception e) {
> >>>             throw new RuntimeException(e);
> >>>         }
> >>>
> >>>
> >>>         ExtendedSqlMapClient client =
> >>> (ExtendedSqlMapClient)factoryBean.getObject();
> >>>
> >>>
> >>>         RoutingSqlMapClient routingClientMap =
> >>>
> >>
> (RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
> >>>         // update reference to SqlMapClient
> >>>         routingClientMap.setTargetSqlMapClient(client);
> >>>
> >>>         // Update the TransactionManager to use the new DataSource
> >>>         DataSourceTransactionManager myTransMgr =
> >>> (DataSourceTransactionManager) ContextManager.getContext
> >>> ().getBean("transactionManager");
> >>>         myTransMgr.setDataSource(projectDS);
> >>>         myTransMgr.afterPropertiesSet();
> >>>
> >>>         // Test that it now accesses the correct database and that
> >>> transactions are
> >>>         // still working
> >>>         sites = siteOps.getSites(requestParams, null);
> >>>         try {
> >>>             site.setId(null);
> >>>             siteOps.saveSite(null, site);
> >>>         }
> >>>         catch (Exception e) {
> >>>             e.printStackTrace();
> >>>         }
> >>>     }
> >>> }
> >>>
> >>>
> >>> Context File:
> >>> <beans>
> >>>
> >>>     <!-- ========================= RESOURCE DEFINITIONS
> >>> ========================= -->
> >>>
> >>>     <bean id="dataSource"
> >>>         class="org.apache.commons.dbcp.BasicDataSource"
> >>>         destroy-method="close">
> >>>         <property name="driverClassName" value="${dbunit.driverClass}"
> >> />
> >>>         <property name="url" value="${dbunit.connectionUrl}" />
> >>>         <property name="username" value="${dbunit.username}" />
> >>>         <property name="password" value="${dbunit.password}" />
> >>>     </bean>
> >>>
> >>>     <!-- Transaction manager for a single JDBC DataSource -->
> >>>     <bean id="transactionManager"
> >>>         class="
> >>> org.springframework.jdbc.datasource.DataSourceTransactionManager">
> >>>         <property name="dataSource" ref="dataSource" />
> >>>     </bean>
> >>>
> >>>     <!-- SqlMap setup for iBATIS Database Layer -->
> >>>     <bean id="sqlMapClient"
> >>>         class="org.springframework.orm.ibatis.SqlMapClientFactoryBean
> ">
> >>>         <property name="configLocation"
> >>>             value="config/sqlmaps/sql-map-config.xml" />
> >>>         <property name="dataSource" ref="dataSource" />
> >>>     </bean>
> >>>
> >>>     <bean id="projSqlMapClient"
> >>>         class="com.foo.persistence.dao.RoutingSqlMapClient">
> >>>         <property name="targetSqlMapClient" ref="sqlMapClient"/>
> >>>     </bean>
> >>>
> >>>     <!-- ========================= DAO DEFINITIONS: IBATIS
> >> IMPLEMENTATIONS
> >>> ========================= -->
> >>>
> >>>     <bean id="customerDao"
> >>>         class="com.foo.persistence.dao.CustomerDaoImpl">
> >>>         <property name="sqlMapClient" ref="sqlMapClient" />
> >>>     </bean>
> >>>
> >>>     <bean id="projectDao"
> >>>         class="com.foo.persistence.dao.ProjectDaoImpl">
> >>>         <property name="sqlMapClient" ref="sqlMapClient" />
> >>>     </bean>
> >>>
> >>>     <bean id="siteDao"
> >>>         class="com.foo.persistence.dao.SiteDaoImpl">
> >>>         <property name="sqlMapClient" ref="projSqlMapClient" />
> >>>     </bean>
> >>>
> >>> </beans>
> >>>
> >>> On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
> >>>>
> >>>> Spring isn't good at dynamic DataSource stuff, especially new ones
> that
> >>>> get
> >>>> created after the Spring context is instantiated.
> >>>>
> >>>> This item on the FAQ details the solution I came up with for my
> stuff:
> >>>>
> >>>>
> >>>>
> >>
> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
> >>>> 12583003
> >>>>
> >>>> There aren't any issues with caching, but the DataSources must be
> known
> >> at
> >>>> Spring creation time which I don't think will work for you.
> >>>>
> >>>> I've been thinking up different ways of doing this so I don't have to
> >> rely
> >>>> on code changes to get a new datasource running, but I haven't spent
> >> much
> >>>> time on it.  It would be much easier to do without Spring, you could
> >> just
> >>>> use iBATIS directly and create sqlmapclients with a properties object
> >> to
> >>>> configure it.  But Spring offers a lot of nice stuff which I don't
> want
> >> to
> >>>> get rid of...
> >>>>
> >>>> Cheers,
> >>>> Chris
> >>>>
> >>>> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <
> >> fearghal.omaolcatha@gmail.com>
> >>>> wrote:
> >>>>
> >>>>> Hi,
> >>>>>
> >>>>> Our project is currently using Ibatis and the Ibatis DAOs. We plan
> to
> >>>>> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
> >>>> enough.
> >>>>> However we have a new requirement that will necessitate the changing
> >> of
> >>>> the
> >>>>> datasource at runtime. Our application has the notion of projects,
> >> with
> >>>> each
> >>>>> new project created by the user requiring a new database (same DB
> >> schema
> >>>> for
> >>>>> all projects). Any new work within the project will be saved to the
> >>>> newly
> >>>>> created database. The user can close a project and open an existing
> >> one,
> >>>>> which would require the datasource to be changed. I've had a look at
> a
> >>>>> previous thread
> >>>>>
> >>
> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
> >>>>> addresses a similar issue but the suggested implementation (wrapping
> >> the
> >>>>> datasource being injected into the SqlMapClient) would have
> >> implications
> >>>> for
> >>>>> the Ibatis cache from what I've read previously. We currently don't
> >> use
> >>>> the
> >>>>> Ibatis cache but might have to for performance reasons in the
> future.
> >>>>>
> >>>>> Any suggestions on how to proceed with this would be welcome.
> >>>>>
> >>>>> Regards,
> >>>>> Fearghal.
> >>>>
> >>>>
> >>
> >>
>
>

Re: Changing datasource at runtime

Posted by Christopher Lamey <cl...@localmatters.com>.
OK - got it.

So I think that'll work.

You could also create a new Spring context when the DS changes and not do
the routing.

Or if you don't need caching, then you could just change the DS and use a
single sqlmapclient.

On 1/15/08 2:25 PM, "Fearghal O Maolcatha" <fe...@gmail.com>
wrote:

> My logic (flawed as it might be) was that I needed a wrapper for the
> SqlMapClient. Each DAO would be injected with a wrapper
> (RoutingSqlMapClient) for a SqlMapClient. When the datasource changes, I
> construct a new SqlMapClient and update the reference in RoutingSqlMapClient
> with the new SqlMapClient. The DAO is unaware of any changes to the
> underlying datasource.
> 
> 
> On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>> 
>> I'm confused - why do you need the routing if you only need to support
>> access to one db at a time?
>> 
>> On 1/15/08 10:41 AM, "Fearghal O Maolcatha" <fearghal.omaolcatha@gmail.com
>>> 
>> wrote:
>> 
>>> Hi Chris,
>>> 
>>> Thanks for the response. I'd actually seen your solution previously. I
>> was
>>> using it as a starting point for what I was trying to do, specifically
>> the
>>> RoutingSqlMapClient class. I've modified it slightly for my purposes to
>> just
>>> contain a reference to one SqlMapClient. We only need to support access
>> to
>>> one database at a time.The bean 'projSqlMapClient' is injected with a
>> known
>>> database at startup. I've included some test code, where I construct a
>> new
>>> DataSource and update the projSqlMapClient bean with the newly
>> constructed
>>> SqlMapClient. It seems to work for the simple test case I've written but
>>> there might be something I've overlooked. I'd appreciate any feedback
>> you
>>> might have on this approach.
>>> 
>>> Thanks,
>>> Fearghal.
>>> 
>>> 
>>> 
>>> public class TestSpringContext {
>>> 
>>>     public static void main(String[] args) throws Exception {
>>>         ContextManager.getContext();
>>> 
>>>         // Create DataSource for the new database
>>>         BasicDataSource projectDS = new BasicDataSource();
>>>         projectDS.setPassword("NsdSa123");
>>>         projectDS.setDriverClassName("
>>> com.microsoft.sqlserver.jdbc.SQLServerDriver");
>>>         projectDS.setUrl
>>> ("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
>>>         projectDS.setUsername("Sa");
>>> 
>>>         // Create a SqlMapClient for the new DataSource
>>>         SqlMapClientFactoryBean factoryBean = new
>> SqlMapClientFactoryBean();
>>>         Resource resource = new ClassPathResource("config/sqlmaps/sql-
>>> map-config.xml");
>>>         factoryBean.setConfigLocation(resource);
>>>         factoryBean.setDataSource(projectDS);
>>>         try {
>>>             factoryBean.afterPropertiesSet();
>>>         } catch (Exception e) {
>>>             throw new RuntimeException(e);
>>>         }
>>> 
>>> 
>>>         ExtendedSqlMapClient client =
>>> (ExtendedSqlMapClient)factoryBean.getObject();
>>> 
>>> 
>>>         RoutingSqlMapClient routingClientMap =
>>> 
>> (RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
>>>         // update reference to SqlMapClient
>>>         routingClientMap.setTargetSqlMapClient(client);
>>> 
>>>         // Update the TransactionManager to use the new DataSource
>>>         DataSourceTransactionManager myTransMgr =
>>> (DataSourceTransactionManager) ContextManager.getContext
>>> ().getBean("transactionManager");
>>>         myTransMgr.setDataSource(projectDS);
>>>         myTransMgr.afterPropertiesSet();
>>> 
>>>         // Test that it now accesses the correct database and that
>>> transactions are
>>>         // still working
>>>         sites = siteOps.getSites(requestParams, null);
>>>         try {
>>>             site.setId(null);
>>>             siteOps.saveSite(null, site);
>>>         }
>>>         catch (Exception e) {
>>>             e.printStackTrace();
>>>         }
>>>     }
>>> }
>>> 
>>> 
>>> Context File:
>>> <beans>
>>> 
>>>     <!-- ========================= RESOURCE DEFINITIONS
>>> ========================= -->
>>> 
>>>     <bean id="dataSource"
>>>         class="org.apache.commons.dbcp.BasicDataSource"
>>>         destroy-method="close">
>>>         <property name="driverClassName" value="${dbunit.driverClass}"
>> />
>>>         <property name="url" value="${dbunit.connectionUrl}" />
>>>         <property name="username" value="${dbunit.username}" />
>>>         <property name="password" value="${dbunit.password}" />
>>>     </bean>
>>> 
>>>     <!-- Transaction manager for a single JDBC DataSource -->
>>>     <bean id="transactionManager"
>>>         class="
>>> org.springframework.jdbc.datasource.DataSourceTransactionManager">
>>>         <property name="dataSource" ref="dataSource" />
>>>     </bean>
>>> 
>>>     <!-- SqlMap setup for iBATIS Database Layer -->
>>>     <bean id="sqlMapClient"
>>>         class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
>>>         <property name="configLocation"
>>>             value="config/sqlmaps/sql-map-config.xml" />
>>>         <property name="dataSource" ref="dataSource" />
>>>     </bean>
>>> 
>>>     <bean id="projSqlMapClient"
>>>         class="com.foo.persistence.dao.RoutingSqlMapClient">
>>>         <property name="targetSqlMapClient" ref="sqlMapClient"/>
>>>     </bean>
>>> 
>>>     <!-- ========================= DAO DEFINITIONS: IBATIS
>> IMPLEMENTATIONS
>>> ========================= -->
>>> 
>>>     <bean id="customerDao"
>>>         class="com.foo.persistence.dao.CustomerDaoImpl">
>>>         <property name="sqlMapClient" ref="sqlMapClient" />
>>>     </bean>
>>> 
>>>     <bean id="projectDao"
>>>         class="com.foo.persistence.dao.ProjectDaoImpl">
>>>         <property name="sqlMapClient" ref="sqlMapClient" />
>>>     </bean>
>>> 
>>>     <bean id="siteDao"
>>>         class="com.foo.persistence.dao.SiteDaoImpl">
>>>         <property name="sqlMapClient" ref="projSqlMapClient" />
>>>     </bean>
>>> 
>>> </beans>
>>> 
>>> On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>>>> 
>>>> Spring isn't good at dynamic DataSource stuff, especially new ones that
>>>> get
>>>> created after the Spring context is instantiated.
>>>> 
>>>> This item on the FAQ details the solution I came up with for my stuff:
>>>> 
>>>> 
>>>> 
>> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
>>>> 12583003
>>>> 
>>>> There aren't any issues with caching, but the DataSources must be known
>> at
>>>> Spring creation time which I don't think will work for you.
>>>> 
>>>> I've been thinking up different ways of doing this so I don't have to
>> rely
>>>> on code changes to get a new datasource running, but I haven't spent
>> much
>>>> time on it.  It would be much easier to do without Spring, you could
>> just
>>>> use iBATIS directly and create sqlmapclients with a properties object
>> to
>>>> configure it.  But Spring offers a lot of nice stuff which I don't want
>> to
>>>> get rid of...
>>>> 
>>>> Cheers,
>>>> Chris
>>>> 
>>>> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <
>> fearghal.omaolcatha@gmail.com>
>>>> wrote:
>>>> 
>>>>> Hi,
>>>>> 
>>>>> Our project is currently using Ibatis and the Ibatis DAOs. We plan to
>>>>> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
>>>> enough.
>>>>> However we have a new requirement that will necessitate the changing
>> of
>>>> the
>>>>> datasource at runtime. Our application has the notion of projects,
>> with
>>>> each
>>>>> new project created by the user requiring a new database (same DB
>> schema
>>>> for
>>>>> all projects). Any new work within the project will be saved to the
>>>> newly
>>>>> created database. The user can close a project and open an existing
>> one,
>>>>> which would require the datasource to be changed. I've had a look at a
>>>>> previous thread
>>>>> 
>> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
>>>>> addresses a similar issue but the suggested implementation (wrapping
>> the
>>>>> datasource being injected into the SqlMapClient) would have
>> implications
>>>> for
>>>>> the Ibatis cache from what I've read previously. We currently don't
>> use
>>>> the
>>>>> Ibatis cache but might have to for performance reasons in the future.
>>>>> 
>>>>> Any suggestions on how to proceed with this would be welcome.
>>>>> 
>>>>> Regards,
>>>>> Fearghal.
>>>> 
>>>> 
>> 
>> 


Re: Changing datasource at runtime

Posted by Fearghal O Maolcatha <fe...@gmail.com>.
My logic (flawed as it might be) was that I needed a wrapper for the
SqlMapClient. Each DAO would be injected with a wrapper
(RoutingSqlMapClient) for a SqlMapClient. When the datasource changes, I
construct a new SqlMapClient and update the reference in RoutingSqlMapClient
with the new SqlMapClient. The DAO is unaware of any changes to the
underlying datasource.


On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>
> I'm confused - why do you need the routing if you only need to support
> access to one db at a time?
>
> On 1/15/08 10:41 AM, "Fearghal O Maolcatha" <fearghal.omaolcatha@gmail.com
> >
> wrote:
>
> > Hi Chris,
> >
> > Thanks for the response. I'd actually seen your solution previously. I
> was
> > using it as a starting point for what I was trying to do, specifically
> the
> > RoutingSqlMapClient class. I've modified it slightly for my purposes to
> just
> > contain a reference to one SqlMapClient. We only need to support access
> to
> > one database at a time.The bean 'projSqlMapClient' is injected with a
> known
> > database at startup. I've included some test code, where I construct a
> new
> > DataSource and update the projSqlMapClient bean with the newly
> constructed
> > SqlMapClient. It seems to work for the simple test case I've written but
> > there might be something I've overlooked. I'd appreciate any feedback
> you
> > might have on this approach.
> >
> > Thanks,
> > Fearghal.
> >
> >
> >
> > public class TestSpringContext {
> >
> >     public static void main(String[] args) throws Exception {
> >         ContextManager.getContext();
> >
> >         // Create DataSource for the new database
> >         BasicDataSource projectDS = new BasicDataSource();
> >         projectDS.setPassword("NsdSa123");
> >         projectDS.setDriverClassName("
> > com.microsoft.sqlserver.jdbc.SQLServerDriver");
> >         projectDS.setUrl
> > ("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
> >         projectDS.setUsername("Sa");
> >
> >         // Create a SqlMapClient for the new DataSource
> >         SqlMapClientFactoryBean factoryBean = new
> SqlMapClientFactoryBean();
> >         Resource resource = new ClassPathResource("config/sqlmaps/sql-
> > map-config.xml");
> >         factoryBean.setConfigLocation(resource);
> >         factoryBean.setDataSource(projectDS);
> >         try {
> >             factoryBean.afterPropertiesSet();
> >         } catch (Exception e) {
> >             throw new RuntimeException(e);
> >         }
> >
> >
> >         ExtendedSqlMapClient client =
> > (ExtendedSqlMapClient)factoryBean.getObject();
> >
> >
> >         RoutingSqlMapClient routingClientMap =
> >
> (RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
> >         // update reference to SqlMapClient
> >         routingClientMap.setTargetSqlMapClient(client);
> >
> >         // Update the TransactionManager to use the new DataSource
> >         DataSourceTransactionManager myTransMgr =
> > (DataSourceTransactionManager) ContextManager.getContext
> > ().getBean("transactionManager");
> >         myTransMgr.setDataSource(projectDS);
> >         myTransMgr.afterPropertiesSet();
> >
> >         // Test that it now accesses the correct database and that
> > transactions are
> >         // still working
> >         sites = siteOps.getSites(requestParams, null);
> >         try {
> >             site.setId(null);
> >             siteOps.saveSite(null, site);
> >         }
> >         catch (Exception e) {
> >             e.printStackTrace();
> >         }
> >     }
> > }
> >
> >
> > Context File:
> > <beans>
> >
> >     <!-- ========================= RESOURCE DEFINITIONS
> > ========================= -->
> >
> >     <bean id="dataSource"
> >         class="org.apache.commons.dbcp.BasicDataSource"
> >         destroy-method="close">
> >         <property name="driverClassName" value="${dbunit.driverClass}"
> />
> >         <property name="url" value="${dbunit.connectionUrl}" />
> >         <property name="username" value="${dbunit.username}" />
> >         <property name="password" value="${dbunit.password}" />
> >     </bean>
> >
> >     <!-- Transaction manager for a single JDBC DataSource -->
> >     <bean id="transactionManager"
> >         class="
> > org.springframework.jdbc.datasource.DataSourceTransactionManager">
> >         <property name="dataSource" ref="dataSource" />
> >     </bean>
> >
> >     <!-- SqlMap setup for iBATIS Database Layer -->
> >     <bean id="sqlMapClient"
> >         class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
> >         <property name="configLocation"
> >             value="config/sqlmaps/sql-map-config.xml" />
> >         <property name="dataSource" ref="dataSource" />
> >     </bean>
> >
> >     <bean id="projSqlMapClient"
> >         class="com.foo.persistence.dao.RoutingSqlMapClient">
> >         <property name="targetSqlMapClient" ref="sqlMapClient"/>
> >     </bean>
> >
> >     <!-- ========================= DAO DEFINITIONS: IBATIS
> IMPLEMENTATIONS
> > ========================= -->
> >
> >     <bean id="customerDao"
> >         class="com.foo.persistence.dao.CustomerDaoImpl">
> >         <property name="sqlMapClient" ref="sqlMapClient" />
> >     </bean>
> >
> >     <bean id="projectDao"
> >         class="com.foo.persistence.dao.ProjectDaoImpl">
> >         <property name="sqlMapClient" ref="sqlMapClient" />
> >     </bean>
> >
> >     <bean id="siteDao"
> >         class="com.foo.persistence.dao.SiteDaoImpl">
> >         <property name="sqlMapClient" ref="projSqlMapClient" />
> >     </bean>
> >
> > </beans>
> >
> > On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
> >>
> >> Spring isn't good at dynamic DataSource stuff, especially new ones that
> >> get
> >> created after the Spring context is instantiated.
> >>
> >> This item on the FAQ details the solution I came up with for my stuff:
> >>
> >>
> >>
> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
> >> 12583003
> >>
> >> There aren't any issues with caching, but the DataSources must be known
> at
> >> Spring creation time which I don't think will work for you.
> >>
> >> I've been thinking up different ways of doing this so I don't have to
> rely
> >> on code changes to get a new datasource running, but I haven't spent
> much
> >> time on it.  It would be much easier to do without Spring, you could
> just
> >> use iBATIS directly and create sqlmapclients with a properties object
> to
> >> configure it.  But Spring offers a lot of nice stuff which I don't want
> to
> >> get rid of...
> >>
> >> Cheers,
> >> Chris
> >>
> >> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <
> fearghal.omaolcatha@gmail.com>
> >> wrote:
> >>
> >>> Hi,
> >>>
> >>> Our project is currently using Ibatis and the Ibatis DAOs. We plan to
> >>> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
> >> enough.
> >>> However we have a new requirement that will necessitate the changing
> of
> >> the
> >>> datasource at runtime. Our application has the notion of projects,
> with
> >> each
> >>> new project created by the user requiring a new database (same DB
> schema
> >> for
> >>> all projects). Any new work within the project will be saved to the
> >> newly
> >>> created database. The user can close a project and open an existing
> one,
> >>> which would require the datasource to be changed. I've had a look at a
> >>> previous thread
> >>>
> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
> >>> addresses a similar issue but the suggested implementation (wrapping
> the
> >>> datasource being injected into the SqlMapClient) would have
> implications
> >> for
> >>> the Ibatis cache from what I've read previously. We currently don't
> use
> >> the
> >>> Ibatis cache but might have to for performance reasons in the future.
> >>>
> >>> Any suggestions on how to proceed with this would be welcome.
> >>>
> >>> Regards,
> >>> Fearghal.
> >>
> >>
>
>

Re: Changing datasource at runtime

Posted by Daniel Solera <ds...@gmail.com>.
Hi,

I think that to make a dynamic DataSource you can make yourself DAO with two
instances of SqlMapClient, and in each moment you can decide which DAO do
you get ....

In this URL you can more information about this, it's easy.
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html


2008/1/15, Christopher Lamey <cl...@localmatters.com>:
>
> I'm confused - why do you need the routing if you only need to support
> access to one db at a time?
>
> On 1/15/08 10:41 AM, "Fearghal O Maolcatha" <fearghal.omaolcatha@gmail.com
> >
> wrote:
>
> > Hi Chris,
> >
> > Thanks for the response. I'd actually seen your solution previously. I
> was
> > using it as a starting point for what I was trying to do, specifically
> the
> > RoutingSqlMapClient class. I've modified it slightly for my purposes to
> just
> > contain a reference to one SqlMapClient. We only need to support access
> to
> > one database at a time.The bean 'projSqlMapClient' is injected with a
> known
> > database at startup. I've included some test code, where I construct a
> new
> > DataSource and update the projSqlMapClient bean with the newly
> constructed
> > SqlMapClient. It seems to work for the simple test case I've written but
> > there might be something I've overlooked. I'd appreciate any feedback
> you
> > might have on this approach.
> >
> > Thanks,
> > Fearghal.
> >
> >
> >
> > public class TestSpringContext {
> >
> >     public static void main(String[] args) throws Exception {
> >         ContextManager.getContext();
> >
> >         // Create DataSource for the new database
> >         BasicDataSource projectDS = new BasicDataSource();
> >         projectDS.setPassword("NsdSa123");
> >         projectDS.setDriverClassName("
> > com.microsoft.sqlserver.jdbc.SQLServerDriver");
> >         projectDS.setUrl
> > ("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
> >         projectDS.setUsername("Sa");
> >
> >         // Create a SqlMapClient for the new DataSource
> >         SqlMapClientFactoryBean factoryBean = new
> SqlMapClientFactoryBean();
> >         Resource resource = new ClassPathResource("config/sqlmaps/sql-
> > map-config.xml");
> >         factoryBean.setConfigLocation(resource);
> >         factoryBean.setDataSource(projectDS);
> >         try {
> >             factoryBean.afterPropertiesSet();
> >         } catch (Exception e) {
> >             throw new RuntimeException(e);
> >         }
> >
> >
> >         ExtendedSqlMapClient client =
> > (ExtendedSqlMapClient)factoryBean.getObject();
> >
> >
> >         RoutingSqlMapClient routingClientMap =
> >
> (RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
> >         // update reference to SqlMapClient
> >         routingClientMap.setTargetSqlMapClient(client);
> >
> >         // Update the TransactionManager to use the new DataSource
> >         DataSourceTransactionManager myTransMgr =
> > (DataSourceTransactionManager) ContextManager.getContext
> > ().getBean("transactionManager");
> >         myTransMgr.setDataSource(projectDS);
> >         myTransMgr.afterPropertiesSet();
> >
> >         // Test that it now accesses the correct database and that
> > transactions are
> >         // still working
> >         sites = siteOps.getSites(requestParams, null);
> >         try {
> >             site.setId(null);
> >             siteOps.saveSite(null, site);
> >         }
> >         catch (Exception e) {
> >             e.printStackTrace();
> >         }
> >     }
> > }
> >
> >
> > Context File:
> > <beans>
> >
> >     <!-- ========================= RESOURCE DEFINITIONS
> > ========================= -->
> >
> >     <bean id="dataSource"
> >         class="org.apache.commons.dbcp.BasicDataSource"
> >         destroy-method="close">
> >         <property name="driverClassName" value="${dbunit.driverClass}"
> />
> >         <property name="url" value="${dbunit.connectionUrl}" />
> >         <property name="username" value="${dbunit.username}" />
> >         <property name="password" value="${dbunit.password}" />
> >     </bean>
> >
> >     <!-- Transaction manager for a single JDBC DataSource -->
> >     <bean id="transactionManager"
> >         class="
> > org.springframework.jdbc.datasource.DataSourceTransactionManager">
> >         <property name="dataSource" ref="dataSource" />
> >     </bean>
> >
> >     <!-- SqlMap setup for iBATIS Database Layer -->
> >     <bean id="sqlMapClient"
> >         class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
> >         <property name="configLocation"
> >             value="config/sqlmaps/sql-map-config.xml" />
> >         <property name="dataSource" ref="dataSource" />
> >     </bean>
> >
> >     <bean id="projSqlMapClient"
> >         class="com.foo.persistence.dao.RoutingSqlMapClient">
> >         <property name="targetSqlMapClient" ref="sqlMapClient"/>
> >     </bean>
> >
> >     <!-- ========================= DAO DEFINITIONS: IBATIS
> IMPLEMENTATIONS
> > ========================= -->
> >
> >     <bean id="customerDao"
> >         class="com.foo.persistence.dao.CustomerDaoImpl">
> >         <property name="sqlMapClient" ref="sqlMapClient" />
> >     </bean>
> >
> >     <bean id="projectDao"
> >         class="com.foo.persistence.dao.ProjectDaoImpl">
> >         <property name="sqlMapClient" ref="sqlMapClient" />
> >     </bean>
> >
> >     <bean id="siteDao"
> >         class="com.foo.persistence.dao.SiteDaoImpl">
> >         <property name="sqlMapClient" ref="projSqlMapClient" />
> >     </bean>
> >
> > </beans>
> >
> > On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
> >>
> >> Spring isn't good at dynamic DataSource stuff, especially new ones that
> >> get
> >> created after the Spring context is instantiated.
> >>
> >> This item on the FAQ details the solution I came up with for my stuff:
> >>
> >>
> >>
> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
> >> 12583003
> >>
> >> There aren't any issues with caching, but the DataSources must be known
> at
> >> Spring creation time which I don't think will work for you.
> >>
> >> I've been thinking up different ways of doing this so I don't have to
> rely
> >> on code changes to get a new datasource running, but I haven't spent
> much
> >> time on it.  It would be much easier to do without Spring, you could
> just
> >> use iBATIS directly and create sqlmapclients with a properties object
> to
> >> configure it.  But Spring offers a lot of nice stuff which I don't want
> to
> >> get rid of...
> >>
> >> Cheers,
> >> Chris
> >>
> >> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <
> fearghal.omaolcatha@gmail.com>
> >> wrote:
> >>
> >>> Hi,
> >>>
> >>> Our project is currently using Ibatis and the Ibatis DAOs. We plan to
> >>> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
> >> enough.
> >>> However we have a new requirement that will necessitate the changing
> of
> >> the
> >>> datasource at runtime. Our application has the notion of projects,
> with
> >> each
> >>> new project created by the user requiring a new database (same DB
> schema
> >> for
> >>> all projects). Any new work within the project will be saved to the
> >> newly
> >>> created database. The user can close a project and open an existing
> one,
> >>> which would require the datasource to be changed. I've had a look at a
> >>> previous thread
> >>>
> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
> >>> addresses a similar issue but the suggested implementation (wrapping
> the
> >>> datasource being injected into the SqlMapClient) would have
> implications
> >> for
> >>> the Ibatis cache from what I've read previously. We currently don't
> use
> >> the
> >>> Ibatis cache but might have to for performance reasons in the future.
> >>>
> >>> Any suggestions on how to proceed with this would be welcome.
> >>>
> >>> Regards,
> >>> Fearghal.
> >>
> >>
>
>

Re: Changing datasource at runtime

Posted by Christopher Lamey <cl...@localmatters.com>.
I'm confused - why do you need the routing if you only need to support
access to one db at a time?

On 1/15/08 10:41 AM, "Fearghal O Maolcatha" <fe...@gmail.com>
wrote:

> Hi Chris,
> 
> Thanks for the response. I'd actually seen your solution previously. I was
> using it as a starting point for what I was trying to do, specifically the
> RoutingSqlMapClient class. I've modified it slightly for my purposes to just
> contain a reference to one SqlMapClient. We only need to support access to
> one database at a time.The bean 'projSqlMapClient' is injected with a known
> database at startup. I've included some test code, where I construct a new
> DataSource and update the projSqlMapClient bean with the newly constructed
> SqlMapClient. It seems to work for the simple test case I've written but
> there might be something I've overlooked. I'd appreciate any feedback you
> might have on this approach.
> 
> Thanks,
> Fearghal.
> 
> 
> 
> public class TestSpringContext {
> 
>     public static void main(String[] args) throws Exception {
>         ContextManager.getContext();
> 
>         // Create DataSource for the new database
>         BasicDataSource projectDS = new BasicDataSource();
>         projectDS.setPassword("NsdSa123");
>         projectDS.setDriverClassName("
> com.microsoft.sqlserver.jdbc.SQLServerDriver");
>         projectDS.setUrl
> ("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
>         projectDS.setUsername("Sa");
> 
>         // Create a SqlMapClient for the new DataSource
>         SqlMapClientFactoryBean factoryBean = new SqlMapClientFactoryBean();
>         Resource resource = new ClassPathResource("config/sqlmaps/sql-
> map-config.xml");
>         factoryBean.setConfigLocation(resource);
>         factoryBean.setDataSource(projectDS);
>         try {
>             factoryBean.afterPropertiesSet();
>         } catch (Exception e) {
>             throw new RuntimeException(e);
>         }
> 
> 
>         ExtendedSqlMapClient client =
> (ExtendedSqlMapClient)factoryBean.getObject();
> 
> 
>         RoutingSqlMapClient routingClientMap =
> (RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
>         // update reference to SqlMapClient
>         routingClientMap.setTargetSqlMapClient(client);
> 
>         // Update the TransactionManager to use the new DataSource
>         DataSourceTransactionManager myTransMgr =
> (DataSourceTransactionManager) ContextManager.getContext
> ().getBean("transactionManager");
>         myTransMgr.setDataSource(projectDS);
>         myTransMgr.afterPropertiesSet();
> 
>         // Test that it now accesses the correct database and that
> transactions are
>         // still working
>         sites = siteOps.getSites(requestParams, null);
>         try {
>             site.setId(null);
>             siteOps.saveSite(null, site);
>         }
>         catch (Exception e) {
>             e.printStackTrace();
>         }
>     }
> }
> 
> 
> Context File:
> <beans>
> 
>     <!-- ========================= RESOURCE DEFINITIONS
> ========================= -->
> 
>     <bean id="dataSource"
>         class="org.apache.commons.dbcp.BasicDataSource"
>         destroy-method="close">
>         <property name="driverClassName" value="${dbunit.driverClass}" />
>         <property name="url" value="${dbunit.connectionUrl}" />
>         <property name="username" value="${dbunit.username}" />
>         <property name="password" value="${dbunit.password}" />
>     </bean>
> 
>     <!-- Transaction manager for a single JDBC DataSource -->
>     <bean id="transactionManager"
>         class="
> org.springframework.jdbc.datasource.DataSourceTransactionManager">
>         <property name="dataSource" ref="dataSource" />
>     </bean>
> 
>     <!-- SqlMap setup for iBATIS Database Layer -->
>     <bean id="sqlMapClient"
>         class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
>         <property name="configLocation"
>             value="config/sqlmaps/sql-map-config.xml" />
>         <property name="dataSource" ref="dataSource" />
>     </bean>
> 
>     <bean id="projSqlMapClient"
>         class="com.foo.persistence.dao.RoutingSqlMapClient">
>         <property name="targetSqlMapClient" ref="sqlMapClient"/>
>     </bean>
> 
>     <!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS
> ========================= -->
> 
>     <bean id="customerDao"
>         class="com.foo.persistence.dao.CustomerDaoImpl">
>         <property name="sqlMapClient" ref="sqlMapClient" />
>     </bean>
> 
>     <bean id="projectDao"
>         class="com.foo.persistence.dao.ProjectDaoImpl">
>         <property name="sqlMapClient" ref="sqlMapClient" />
>     </bean>
> 
>     <bean id="siteDao"
>         class="com.foo.persistence.dao.SiteDaoImpl">
>         <property name="sqlMapClient" ref="projSqlMapClient" />
>     </bean>
> 
> </beans>
> 
> On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>> 
>> Spring isn't good at dynamic DataSource stuff, especially new ones that
>> get
>> created after the Spring context is instantiated.
>> 
>> This item on the FAQ details the solution I came up with for my stuff:
>> 
>> 
>> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
>> 12583003
>> 
>> There aren't any issues with caching, but the DataSources must be known at
>> Spring creation time which I don't think will work for you.
>> 
>> I've been thinking up different ways of doing this so I don't have to rely
>> on code changes to get a new datasource running, but I haven't spent much
>> time on it.  It would be much easier to do without Spring, you could just
>> use iBATIS directly and create sqlmapclients with a properties object to
>> configure it.  But Spring offers a lot of nice stuff which I don't want to
>> get rid of...
>> 
>> Cheers,
>> Chris
>> 
>> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <fe...@gmail.com>
>> wrote:
>> 
>>> Hi,
>>> 
>>> Our project is currently using Ibatis and the Ibatis DAOs. We plan to
>>> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
>> enough.
>>> However we have a new requirement that will necessitate the changing of
>> the
>>> datasource at runtime. Our application has the notion of projects, with
>> each
>>> new project created by the user requiring a new database (same DB schema
>> for
>>> all projects). Any new work within the project will be saved to the
>> newly
>>> created database. The user can close a project and open an existing one,
>>> which would require the datasource to be changed. I've had a look at a
>>> previous thread
>>> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
>>> addresses a similar issue but the suggested implementation (wrapping the
>>> datasource being injected into the SqlMapClient) would have implications
>> for
>>> the Ibatis cache from what I've read previously. We currently don't use
>> the
>>> Ibatis cache but might have to for performance reasons in the future.
>>> 
>>> Any suggestions on how to proceed with this would be welcome.
>>> 
>>> Regards,
>>> Fearghal.
>> 
>> 


Re: Changing datasource at runtime

Posted by Fearghal O Maolcatha <fe...@gmail.com>.
Hi Chris,

Thanks for the response. I'd actually seen your solution previously. I was
using it as a starting point for what I was trying to do, specifically the
RoutingSqlMapClient class. I've modified it slightly for my purposes to just
contain a reference to one SqlMapClient. We only need to support access to
one database at a time.The bean 'projSqlMapClient' is injected with a known
database at startup. I've included some test code, where I construct a new
DataSource and update the projSqlMapClient bean with the newly constructed
SqlMapClient. It seems to work for the simple test case I've written but
there might be something I've overlooked. I'd appreciate any feedback you
might have on this approach.

Thanks,
Fearghal.



public class TestSpringContext {

    public static void main(String[] args) throws Exception {
        ContextManager.getContext();

        // Create DataSource for the new database
        BasicDataSource projectDS = new BasicDataSource();
        projectDS.setPassword("NsdSa123");
        projectDS.setDriverClassName("
com.microsoft.sqlserver.jdbc.SQLServerDriver");
        projectDS.setUrl
("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=NSD_DB2");
        projectDS.setUsername("Sa");

        // Create a SqlMapClient for the new DataSource
        SqlMapClientFactoryBean factoryBean = new SqlMapClientFactoryBean();
        Resource resource = new ClassPathResource("config/sqlmaps/sql-
map-config.xml");
        factoryBean.setConfigLocation(resource);
        factoryBean.setDataSource(projectDS);
        try {
            factoryBean.afterPropertiesSet();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        ExtendedSqlMapClient client =
(ExtendedSqlMapClient)factoryBean.getObject();


        RoutingSqlMapClient routingClientMap =
(RoutingSqlMapClient)ContextManager.getContext().getBean("projSqlMapClient");
        // update reference to SqlMapClient
        routingClientMap.setTargetSqlMapClient(client);

        // Update the TransactionManager to use the new DataSource
        DataSourceTransactionManager myTransMgr =
(DataSourceTransactionManager) ContextManager.getContext
().getBean("transactionManager");
        myTransMgr.setDataSource(projectDS);
        myTransMgr.afterPropertiesSet();

        // Test that it now accesses the correct database and that
transactions are
        // still working
        sites = siteOps.getSites(requestParams, null);
        try {
            site.setId(null);
            siteOps.saveSite(null, site);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Context File:
<beans>

    <!-- ========================= RESOURCE DEFINITIONS
========================= -->

    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${dbunit.driverClass}" />
        <property name="url" value="${dbunit.connectionUrl}" />
        <property name="username" value="${dbunit.username}" />
        <property name="password" value="${dbunit.password}" />
    </bean>

    <!-- Transaction manager for a single JDBC DataSource -->
    <bean id="transactionManager"
        class="
org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient"
        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation"
            value="config/sqlmaps/sql-map-config.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="projSqlMapClient"
        class="com.foo.persistence.dao.RoutingSqlMapClient">
        <property name="targetSqlMapClient" ref="sqlMapClient"/>
    </bean>

    <!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS
========================= -->

    <bean id="customerDao"
        class="com.foo.persistence.dao.CustomerDaoImpl">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

    <bean id="projectDao"
        class="com.foo.persistence.dao.ProjectDaoImpl">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

    <bean id="siteDao"
        class="com.foo.persistence.dao.SiteDaoImpl">
        <property name="sqlMapClient" ref="projSqlMapClient" />
    </bean>

</beans>

On 15/01/2008, Christopher Lamey <cl...@localmatters.com> wrote:
>
> Spring isn't good at dynamic DataSource stuff, especially new ones that
> get
> created after the Spring context is instantiated.
>
> This item on the FAQ details the solution I came up with for my stuff:
>
>
> http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
> 12583003
>
> There aren't any issues with caching, but the DataSources must be known at
> Spring creation time which I don't think will work for you.
>
> I've been thinking up different ways of doing this so I don't have to rely
> on code changes to get a new datasource running, but I haven't spent much
> time on it.  It would be much easier to do without Spring, you could just
> use iBATIS directly and create sqlmapclients with a properties object to
> configure it.  But Spring offers a lot of nice stuff which I don't want to
> get rid of...
>
> Cheers,
> Chris
>
> On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <fe...@gmail.com>
> wrote:
>
> > Hi,
> >
> > Our project is currently using Ibatis and the Ibatis DAOs. We plan to
> > migrate the Ibatis DAOs to Spring DAOs, which seems straightforward
> enough.
> > However we have a new requirement that will necessitate the changing of
> the
> > datasource at runtime. Our application has the notion of projects, with
> each
> > new project created by the user requiring a new database (same DB schema
> for
> > all projects). Any new work within the project will be saved to the
> newly
> > created database. The user can close a project and open an existing one,
> > which would require the datasource to be changed. I've had a look at a
> > previous thread
> > http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.htmlwhich
> > addresses a similar issue but the suggested implementation (wrapping the
> > datasource being injected into the SqlMapClient) would have implications
> for
> > the Ibatis cache from what I've read previously. We currently don't use
> the
> > Ibatis cache but might have to for performance reasons in the future.
> >
> > Any suggestions on how to proceed with this would be welcome.
> >
> > Regards,
> > Fearghal.
>
>

Re: Changing datasource at runtime

Posted by Christopher Lamey <cl...@localmatters.com>.
Spring isn't good at dynamic DataSource stuff, especially new ones that get
created after the Spring context is instantiated.

This item on the FAQ details the solution I came up with for my stuff:

http://opensource.atlassian.com/confluence/oss/pages/viewpage.action?pageId=
12583003

There aren't any issues with caching, but the DataSources must be known at
Spring creation time which I don't think will work for you.

I've been thinking up different ways of doing this so I don't have to rely
on code changes to get a new datasource running, but I haven't spent much
time on it.  It would be much easier to do without Spring, you could just
use iBATIS directly and create sqlmapclients with a properties object to
configure it.  But Spring offers a lot of nice stuff which I don't want to
get rid of...

Cheers,
Chris

On 1/15/08 8:57 AM, "Fearghal O Maolcatha" <fe...@gmail.com>
wrote:

> Hi,
> 
> Our project is currently using Ibatis and the Ibatis DAOs. We plan to
> migrate the Ibatis DAOs to Spring DAOs, which seems straightforward enough.
> However we have a new requirement that will necessitate the changing of the
> datasource at runtime. Our application has the notion of projects, with each
> new project created by the user requiring a new database (same DB schema for
> all projects). Any new work within the project will be saved to the newly
> created database. The user can close a project and open an existing one,
> which would require the datasource to be changed. I've had a look at a
> previous thread
> http://www.mail-archive.com/user-java@ibatis.apache.org/msg08475.html which
> addresses a similar issue but the suggested implementation (wrapping the
> datasource being injected into the SqlMapClient) would have implications for
> the Ibatis cache from what I've read previously. We currently don't use the
> Ibatis cache but might have to for performance reasons in the future.
> 
> Any suggestions on how to proceed with this would be welcome.
> 
> Regards,
> Fearghal.