Setup Connection Pooling in Spring MVC - spring

How can I setup connection pooling in Spring MVC? I am working on an intranet website powered by Spring MVC 2.5 and jQuery. This is my first attempt at web development.
I am not sure but, I am only using this in my spring configuration file and I saw this in the Spring MVC step By Step tutorial
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
This looks good during development and connection speed is fast but I am not sure if this will still holds true if many users are concurrently connected.
How can I achieve this? I have read that this is not an optimal connection datasource.

You might want to look at c3p0, which has some powerful configuration and optimization available.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="..." />
<property name="jdbcUrl" value="..." />
<property name="user" value="..." />
<property name="password" value="..." />
</bean>

Your current setup is correct, all you need to do in order to use basic connection pooling is use a DataSource implementation provided by a connection pooling library, in your case Apache DBCP. See this post for a few links to other alternatives, C3P0 being one of them.
Note that when you actually use the DataSource bean you're injecting wrap it in a SimpleJdbcTemplate or use DataSourceUtils to obtain a Connection - see Spring JDBC Documentation

For connection Pooling
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
//Add this two more parameters
<property name="**initialSize**" value="20" />
<property name="**maxActive**" value="30" />
</bean>
connection pool will create 20 database connection as initialSize is 20 and goes up to 30 Database connection if required as maxActive is 30.

Related

How to read db properties file for different environments in camel and jenkins

Hi I want read properties for dev,prod environments , Is this any way do this?
I'm doing like below ,but no use
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-
method="close" id="dataSource">
<property name="driverClassName" value="${jdbc.driver.class}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxIdle" value="20"/>
<property name="maxActive" value="20"/>
</bean>
<bean
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"
id="bridgePropertyPlaceholder">
<property name="location" value="classpath:db-${envTarget}.properties"/>
</bean>
I'm doing like this and giving my goal as
clean install -DenvTarget=dev
but not working, please help me here .
Use Spring profiles and environment abstraction for this.
Then you can simply use different property files like db-[profilename].properties and they are automatically loaded according to the active profiles.

Change property value of a existing bean in spring at run time

I have a web application deployed on Tomcat server. I have the following bean hiveDataSource created in my application-context.xml:
<!-- Hive Data Source for Connection Pooling -->
<bean id="hiveDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="url" value="jdbc:hive2://localhost:10000/demo48" />
<property name="driverClassName" value="org.apache.hive.jdbc.HiveDriver" />
<property name="username" value="hive" />
<property name="password" value="" />
<property name="removeAbandoned" value="true" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
</bean>
I want to change the value of property URL, username and password at run time for bean hiveDataSource. Is there any way to change these property values at runtime?
The documentation says that these fields have protected access, so you wont be able to change their values.
Even if you do, by using reflection or in some other way, it's not likely that data source would just pick up these new values. It would probably have to be restarted or reinitialized in some way.

Build Maven project without include Spring bean profile

I use Spring bean profile to separate each datasource environments:
<bean id="fooJDBCTemplate" class="com.rakuya.r_erp.task.dao.FooJDBCTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<beans profile="dev">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://somewhere:3306/erp?characterEncoding=UTF-8" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
</beans>
<beans profile="qa">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://somewhere:3306/erp?characterEncoding=UTF-8"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
</beans>
<beans profile="prod">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://somewhere:3306/erp?characterEncoding=UTF-8"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
</beans>
And i use following command to build jar file and specify profile
mvn clean package -Dspring.profiles.active=prod
But i got the error about no definition of dataSource when executing the jar file.
It seems like Maven does not use the Spring profile to build jar.
How can I configure the Maven or Spring peofile to use the dataSource ?
Thx
You need to pass the profile -D switch when you run your app.
Since your bears are all the same type (DriverManagerDataSource) and the only thing that differs between environments are some of the properties, I think it would be best to get rid of the spring profiles and use properties to set these values. PropertyPlaceholderConfigurer should be able to handle this scenario where you set a vm param specifying what environment you want. Something like -Denv=dev.
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:${env}.properties</value>
</list>
</property>
</bean>
Then you would only need one datasource bean like the following:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
And a property file for each environment named dev.properties, qa.properties, and prod.properties with values in each for db.driver, db.url, etc.
When spring starts up it will select the appropriate properties file based on the value passed in with -Denv and load the corresponding property values into your datasource bean.

Spring Testing with H2 db configuration

I use Oracle in production environment and I would like to use H2 for testing. I can type;
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
so my tables and scripts are created automatically. But I cannot set URL value of this db. (For H2-Oracle compatibility I should add ;MODE=Oracle to url part)
is there a way to achieve this goal?
Or just an opposite solution;
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:file:h2\db"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
in this time, I can edit URL part, but how can I load default test scripts (create and data sqls) to this datasource?
This technique solved the problem;
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
and then adding this tag and definition;
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:testdb/schema.sql" />
<jdbc:script location="classpath:testdb/data.sql" />
</jdbc:initialize-database>
Maybe this will help: H2 supports an INIT script (a SQL script which is executed when opening the connection). The database URL would look like this in the XML file:
<property name="url" value="jdbc:h2:file:h2\db;INIT=
RUNSCRIPT FROM 'classpath:schema.sql'\;
RUNSCRIPT FROM 'classpath:test-data.sql'"/>
(the ; needs to be escaped with a backslash).

Spring service going down after DB connection down

I have a spring cxf web service application deployed into a JBOSS server. The service is working fine and once in a while(within 5-6 days after the server start) , I get and error"Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object" and that particular service goes down
I have around 17 services inside this application and only the service which had this DB connection issue goes down till I restart the server.
Other services are up.
Below is my JDBC template configuration.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="10" />
<property name="maxIdle" value="10" />
<property name="maxActive" value="100" />
<property name="maxWait" value="1000" />
<property name="validationQuery" value="select 1 from sysibm.sysdummy1" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="1200000" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
<property name="numTestsPerEvictionRun" value="5" />
<property name="defaultAutoCommit" value="false" />
</bean>
Your help is greately appreciated.
I'd recommend that you switch to a JNDI data source managed by JBOSS.
It sounds like either a connection leak or that you have some really long-running processes that hold a database connection long-term, eventually exhausting your connection pool. It's also possible, though unlikely, that you have very high database latency, that a dead connection shows up in the pool, and that recognizing the dead connection, establishing a new one, and validating it takes longer than the 1 second you've given the pool.
You can try and change the datasource to the :
org.springframework.jdbc.datasource.DriverManagerDataSource
It's better to configure a data source with JBoss and do a Java EE-jndi lookup.
http://techdive.in/spring/spring-jndi-datasource-configuration-jboss

Resources