You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Stephan Beutel <be...@axivion.com> on 2011/02/09 10:16:59 UTC
Context.xml for multiple datasources
Hello Tomcat users,
I need some help creating my context.xml file in a correct way.
My application is based on Spring and Hibernate. I need to configure
more than one datasource
to access multiple databases at the same time.
This is my working Spring datasource.xml:
<bean id="parentDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="driverClassName" value="org.sqlite.JDBC" />
<property name="username" value="sa" />
</bean>
<bean id="firstDataSource" parent="parentDataSource">
<property name="url" value="jdbc:sqlite:C:\firstDatabase.db" />
</bean>
<bean id="secondDataSource" parent="parentDataSource">
<property name="url" value="jdbc:sqlite:C:\secondDatabase.db" />
</bean>
<bean id="dataSource"
class="com.ax.dashboard.datasource.AxRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="first" value-ref="firstDatasource" />
<entry key="second" value-ref="secondDataSource" />
</map>
</property>
<property name="defaultTargetDataSource" ref="firstDatasource" />
</bean>
Is it possible to create a corresponding context to configure the
databases outside my war file?
I can't find any solution in the web.
Thanks a lot.
Regards,
Stephan
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
Re: Context.xml for multiple datasources
Posted by Stephan Beutel <be...@axivion.com>.
Am 09.02.2011 15:02, schrieb Caldarale, Charles R:
>> From: Stephan Beutel [mailto:beutel@axivion.com]
>> Subject: Re: Context.xml for multiple datasources
>> But I thought it could be defined by a map in
>> context.xml like in Spring.
> Even if you did, that wouldn't solve your problem. You would still have to stop and restart the webapp every time an additional datasource was added to the<Context> element.
>
> You could provide a<Parameter> element nested inside the<Context> that specifies the names of the<Resource> entries, but there's no automatically created list of<Resource> elements.
>
> - Chuck
>
>
> THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
Restarting the webapp is no problem. Rebuilding the war file is a problem.
At the moment I solved it in this was:
<Resource name="jdbc/first" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="org.sqlite.JDBC"
url="jdbc:sqlite:C:\firstDatabase.db"/>
<Resource name="jdbc/second" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="org.sqlite.JDBC"
url="jdbc:sqlite:C:\secondDatabase.db"/>
<Resource name="jdbc/third" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="org.sqlite.JDBC"
url="jdbc:sqlite:C:\thirdDatabase.db"/>
<Environment name="dataSourceNames" value="first, second, third"
type="java.lang.String"
override="false"/>
<Environment name="dataSourceList" value="jdbc/first, jdbc/second,
jdbc/third" type="java.lang.String"
override="false"/>
Spring looks for the two environment vars (dataSourceNames,
dataSourceList) and inject them into my RoutingDataSource class:
<jee:jndi-lookup id="dataSources" jndi-name="dataSourceList" />
<jee:jndi-lookup id="dataSourceNames" jndi-name="dataSourceNames" />
<bean id="dataSource"
class="com.ax.dashboard.datasource.AxRoutingDataSource">
<property name="dataSources" ref="dataSources"/>
<property name="dataSourceNames" ref="dataSourceNames" />
</bean>
And in my java class I do the lookup with JNDI:
private void createDataSourceMap() {
if (this.dataSourceList != null && this.dataSourceNames != null
&& this.dataSourceList.size() > 0
&& this.dataSourceNames.size() > 0 && dataSourceList.size() ==
this.dataSourceNames.size()) {
this.dataSources = new HashMap<Object, Object>();
for (int i = 0; i < dataSourceList.size(); i++) {
Context initCtx;
Object dataSource = null;
try {
initCtx = new InitialContext();
Context envCtx = (Context)
initCtx.lookup("java:comp/env");
dataSource = envCtx.lookup(dataSourceList.get(i));
if(i==0){
setDefaultTargetDataSource(dataSource);
}
} catch (NamingException e) {
e.printStackTrace();
}
dataSources.put(dataSourceNames.get(i), dataSource);
}
setTargetDataSources(dataSources);
}
}
If someone has a better solution, please let me know.
Regards
Stephan
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
RE: Context.xml for multiple datasources
Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Stephan Beutel [mailto:beutel@axivion.com]
> Subject: Re: Context.xml for multiple datasources
> But I thought it could be defined by a map in
> context.xml like in Spring.
Even if you did, that wouldn't solve your problem. You would still have to stop and restart the webapp every time an additional datasource was added to the <Context> element.
You could provide a <Parameter> element nested inside the <Context> that specifies the names of the <Resource> entries, but there's no automatically created list of <Resource> elements.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
Re: Context.xml for multiple datasources
Posted by Stephan Beutel <be...@axivion.com>.
Am 09.02.2011 12:12, schrieb chris derham:
>> That's right, my code doesn't support a variable amount of databases at
>> the moment because
>> the databases are configured in Spring (inside my war file).
>> But if I use the context to configure this list of datasources, the admin
>> can create databases as he need.
>> And that's the reason why my configuration has to take place in the server
>> context and not hardcoded in the Spring configuration.
>> In Spring I can add more databases as I want, but I have to rebuild my war
>> file after change the datasource.
>> With a context configuration my war file can handle as many databases as
>> the admin configures.
>> The switch is done by the key of the map.
>>
> So why don't you have a string resource in the context that provides the
> jndi names of all the jndi data sources, e.g.
> mydatasourceJndiNames=name1,name2,name3. Then have some code the lazily
> loads this string, splits it, and then loads these via jndi into your map?
>
> Chris
>
That's the thing I work on at the moment.
But I thought it could be defined by a map in context.xml like in Spring.
Stephan
--
*Stephan Beutel (B.Eng.)*
Senior Software Developer
Axivion GmbH
Nobelstr. 15
70569 Stuttgart
Germany
Tel: +49 711 6204378-66
Fax: +49 711 6204378-99
Mail: beutel@axivion.com <ma...@axivion.com>
URL: http://www.axivion.com
Geschaeftsfuehrung: Stefan Bellon, Thomas Eisenbarth, Sebastian Rummler
Sitz der Gesellschaft: Stuttgart
Registergericht: Amtsgericht Stuttgart, HRB 720590
Re: Context.xml for multiple datasources
Posted by chris derham <ch...@derham.me.uk>.
>
> That's right, my code doesn't support a variable amount of databases at
> the moment because
> the databases are configured in Spring (inside my war file).
> But if I use the context to configure this list of datasources, the admin
> can create databases as he need.
> And that's the reason why my configuration has to take place in the server
> context and not hardcoded in the Spring configuration.
> In Spring I can add more databases as I want, but I have to rebuild my war
> file after change the datasource.
> With a context configuration my war file can handle as many databases as
> the admin configures.
> The switch is done by the key of the map.
>
So why don't you have a string resource in the context that provides the
jndi names of all the jndi data sources, e.g.
mydatasourceJndiNames=name1,name2,name3. Then have some code the lazily
loads this string, splits it, and then loads these via jndi into your map?
Chris
Re: Context.xml for multiple datasources
Posted by Stephan Beutel <be...@axivion.com>.
Am 09.02.2011 11:03, schrieb chris derham:
>> And the question is:
>> How to build the context to move the existing Spring configuration to the
>> Tomcat context to get all datasources with JNDI.
>> The problem is, that it must be possible to set a variable amount of
>> databases. I can't set the number of databases to a fixed amount.
>>
> Building the Resources for the beans named parentDataSource, firstDataSource
>> and secondDataSource is like configuring a single database.
>> But How can I create a JNDI lookable resource like the bean named
>> dataSource containing a map of all available database resources?
>>
> > From your original post, in which you stated "This is my working Spring
> datasource.xml:"
>
> <bean id="dataSource" class="com.ax.dashboard.
> datasource.AxRoutingDataSource">
> <property name="targetDataSources">
> <map key-type="java.lang.String">
> <entry key="first" value-ref="firstDatasource" />
> <entry key="second" value-ref="secondDataSource" />
> </map>
> </property>
> <property name="defaultTargetDataSource" ref="firstDatasource" />
> </bean>
>
> In spring you are building a map of data sources that are also defined in
> spring. Why not build a map of data sources that are defined in context.xml
> and spring looks them up? You say that you need variable amounts of
> databases, but the code you posted and said "this worked" doesn't support
> this - to add a new datasource you would have to update spring config. If
> you really need variable databases, then some custom code to load a custom
> configuration of such data sources might be the way to go. Then just use a
> resource element in context to get tomcat to load that for the instance.
>
> Chris
>
That's right, my code doesn't support a variable amount of databases at
the moment because
the databases are configured in Spring (inside my war file).
But if I use the context to configure this list of datasources, the
admin can create databases as he need.
And that's the reason why my configuration has to take place in the
server context and not hardcoded in the Spring configuration.
In Spring I can add more databases as I want, but I have to rebuild my
war file after change the datasource.
With a context configuration my war file can handle as many databases as
the admin configures.
The switch is done by the key of the map.
Stephan
--
*Stephan Beutel (B.Eng.)*
Senior Software Developer
Axivion GmbH
Nobelstr. 15
70569 Stuttgart
Germany
Tel: +49 711 6204378-66
Fax: +49 711 6204378-99
Mail: beutel@axivion.com <ma...@axivion.com>
URL: http://www.axivion.com
Geschaeftsfuehrung: Stefan Bellon, Thomas Eisenbarth, Sebastian Rummler
Sitz der Gesellschaft: Stuttgart
Registergericht: Amtsgericht Stuttgart, HRB 720590
Re: Context.xml for multiple datasources
Posted by chris derham <ch...@derham.me.uk>.
> And the question is:
> How to build the context to move the existing Spring configuration to the
> Tomcat context to get all datasources with JNDI.
> The problem is, that it must be possible to set a variable amount of
> databases. I can't set the number of databases to a fixed amount.
>
Building the Resources for the beans named parentDataSource, firstDataSource
> and secondDataSource is like configuring a single database.
> But How can I create a JNDI lookable resource like the bean named
> dataSource containing a map of all available database resources?
>
>From your original post, in which you stated "This is my working Spring
datasource.xml:"
<bean id="dataSource" class="com.ax.dashboard.
datasource.AxRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="first" value-ref="firstDatasource" />
<entry key="second" value-ref="secondDataSource" />
</map>
</property>
<property name="defaultTargetDataSource" ref="firstDatasource" />
</bean>
In spring you are building a map of data sources that are also defined in
spring. Why not build a map of data sources that are defined in context.xml
and spring looks them up? You say that you need variable amounts of
databases, but the code you posted and said "this worked" doesn't support
this - to add a new datasource you would have to update spring config. If
you really need variable databases, then some custom code to load a custom
configuration of such data sources might be the way to go. Then just use a
resource element in context to get tomcat to load that for the instance.
Chris
Re: Context.xml for multiple datasources
Posted by Stephan Beutel <be...@axivion.com>.
Am 09.02.2011 10:30, schrieb chris derham:
>> I need some help creating my context.xml file in a correct way.
>>
>> My application is based on Spring and Hibernate. I need to configure more
>> than one datasource
>> to access multiple databases at the same time.
>>
>>
> We use JNDI to set up our datasource. So in spring configuration, we have
>
> <bean id="dataSource"
> class="org.springframework.jndi.JndiObjectFactoryBean">
> <property name="jndiName" value="java:comp/env/jdbc/myapp" />
> </bean>
>
> Then in<tomcat_base>\conf\context.xml we have
>
> <Context>
> <Resource name="jdbc/myapp"
> auth="Container"
> type="javax.sql.DataSource"
> username="<username>"
> password="<password>"
> driverClassName="oracle.jdbc.OracleDriver"
> url="jdbc:oracle:thin:@localhost:1521:xe"
> maxActive="20"
> maxIdle="2"
> minIdle="1"
> initialSize="2"
> />
> </Context>
>
> This will provide the jndi data source to all apps in the tomcat instance.
> If you wish/need to restrict that to a single war, place the above entry in
> conf/Catalina/[host]/[appName].xml. Using this technique you should be able
> to specify multiple datasources.
>
> Chris
>
Hello,
thank you for the quick answer.
I know how to configure one datasource and lookup with JNDI. This is my
actual configuration.
But I need to configure more than one datasource to switch the database
at runtime.
With my Spring configured datasource it works to access all databases.
But I don't know how to
create a context for Tomcat to access all databases.
------------------
My configuration to access ONE database:
datasource.xml for Spring:
#########
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.sqlite.JDBC</value>
</property>
<property name="url">
<value>jdbc:sqlite:C:\firstDatabase.db</value>
</property>
<property name="username">
<value>SA</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
#########
The same datasource as context to lookup with JNDI:
#########
<Context>
...
<Resource name="jdbc/myds" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="org.sqlite.JDBC"
url="jdbc:sqlite:C:\firstDatabase.db"/>
...
</Context>
#########
Lookup in Spring:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myds"/>
------------------------------------
The configuration I need in my application:
datasource.xml for Spring:
########
<bean id="parentDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="driverClassName" value="org.sqlite.JDBC" />
<property name="username" value="sa" />
</bean>
<bean id="firstDataSource" parent="parentDataSource">
<property name="url" value="jdbc:sqlite:C:\firstDatabase.db" />
</bean>
<bean id="secondDataSource" parent="parentDataSource">
<property name="url" value="jdbc:sqlite:C:\secondDatabase.db" />
</bean>
<bean id="dataSource"
class="com.ax.dashboard.datasource.AxRoutingDataSource">
<property name="testString" ref="testContext"/>
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="first" value-ref="firstDataSource" />
<entry key="second" value-ref="secondDataSource" />
</map>
</property>
<property name="defaultTargetDataSource" ref="firstDataSource" />
</bean>
########
And the question is:
How to build the context to move the existing Spring configuration to
the Tomcat context to get all datasources with JNDI.
The problem is, that it must be possible to set a variable amount of
databases. I can't set the number of databases to a fixed amount.
Building the Resources for the beans named parentDataSource,
firstDataSource and secondDataSource is like configuring a single database.
But How can I create a JNDI lookable resource like the bean named
dataSource containing a map of all available database resources?
Regards
Stephan
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
Re: Context.xml for multiple datasources
Posted by chris derham <ch...@derham.me.uk>.
>
> I need some help creating my context.xml file in a correct way.
>
> My application is based on Spring and Hibernate. I need to configure more
> than one datasource
> to access multiple databases at the same time.
>
>
We use JNDI to set up our datasource. So in spring configuration, we have
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myapp" />
</bean>
Then in <tomcat_base>\conf\context.xml we have
<Context>
<Resource name="jdbc/myapp"
auth="Container"
type="javax.sql.DataSource"
username="<username>"
password="<password>"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:xe"
maxActive="20"
maxIdle="2"
minIdle="1"
initialSize="2"
/>
</Context>
This will provide the jndi data source to all apps in the tomcat instance.
If you wish/need to restrict that to a single war, place the above entry in
conf/Catalina/[host]/[appName].xml. Using this technique you should be able
to specify multiple datasources.
Chris