Configure spring datasource for hibernate and #Transactional - java

At this moment I'm using DriverManagerDataSource with #Transactional annotation to manage transactions. But all transactions are very very slow, probably because data source open and close connection to db each time.
What data source should I use to speed up transaction?

I am using in my application combination of two approaches. the first one is c3p0 connection pooling, its almost the same solution as chkal sugested. The second approach is to use Spring lazyConnectionDataSourceProxy, which creates lazy loading proxy that loads connection only if you hit the database. This is very useful, when you have second level cache and you are only reading cached data and queries - database wont be hit, and you don't need to acquire connection (which is pretty expensive).
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="initialPoolSize" value="10" />
<property name="maxPoolSize" value="50" />
<property name="maxStatements" value="50" />
<property name="idleConnectionTestPeriod" value="120" />
<property name="maxIdleTime" value="1200" />
</bean>
<bean name="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="dataSource" />
</bean>

DriverManagerDataSource isn't actually a connection pool and should only be used for testing. You should try BasicDataSource from Apache Commons DBCP. Something like:
<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}"/>
</bean>

Related

Connection pooling in spring jdbc

I have implemented spring jdbc in my project. I am just curious to know how connection pooling in handled in spring jdbc? If spring is taking care of connections, then where can I specify the max number of connections allowed for my application?
Another question is how is connection pooling handled in simple jdbc.
Please clarify.
You can use own custom datasource, like this:
<bean id="springDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="url" value="jdbc:oracle:thin:#localhost:1521:SPRING_TEST" />
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="20" />
<property name="maxActive" value="30" />
</bean>
//Dao class configuration in spring
<bean id="EmployeeDatabaseBean" class="com.test.EmployeeDAOImpl">
<property name="dataSource" ref="springDataSource"/>
</bean>
Official documentation
Here or here described pretty simple.

how to make below jdbc connection configuration connection pooling

i am having a web application and my application is connected to database for every hit to my web application i need to make a connection to database so i want to reduce time by caching or pooling connection
below is my database configured file
xml file:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
Please use HikariCP for your application, best and very fast connection pool available in java world,configuration should be like below.
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" >
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/" />
<property name="maximumPoolSize" value="20" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="poolName" value="my-pool1" />
</bean>
</constructor-arg>
</bean>
Or you can have programatic configuration as well.
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
config.setUsername("bart");
config.setPassword("51mp50n");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
HikariDataSource ds = new HikariDataSource(config);
You can use as follows , just change your database driver and url settings
<bean id="springDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="url" value="jdbc:oracle:thin:#localhost:1521:Employee" />
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="username" value="scott" />
<property name="password" value="tiger" />
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="20" />
<property name="maxActive" value="30" />
</bean>
You should use SingleConnectionDataSource as datasource
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>

Advantage of org.springframework.jdbc.datasource.DriverManagerDataSource over oracle.jdbc.pool.OracleDataSource

I currently use this configuration for my projects:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="URL" ...
<property name="user" ...
<property name="password" ...
<property name="connectionCachingEnabled" value="true" />
And it works fine, pretty fast.
I happened to see, on an old project (spring 2.5) this configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url"...
<property name="username" ...
<property name="password" ...
</bean>
From documentation it would seem that this last option does not make use of a connection pool. I see no reason to use this configuration over mine, but it still exists so I am curious: where's the advantage/limitation?
1st configuration is oracle specific, whereas 2nd configuration is generic. You can explicitly define driver class.
This is the only major difference I can see in them other than connection pool support of OracleDataSource.
You can use it for generic behavior as mentioned below:
<bean id="baseDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="username" value="user"/>
<property name="password" value="pwd" />
</bean>
<bean id="mySqlDataSource" parent="baseDataSource">
<property name="driverClassName" value="${mySQL.driver}" />
<property name="url" value="${mySQL.url}"/>
</bean>
<bean id="oracleDataSource" parent="baseDataSource">
<property name="driverClassName" value="${oracle.driver}" />
<property name="url" value="${oracle.url}"/>
</bean>
Property values you can externalized.
You can explore Apache Jakarta Commons DBCP which has all the features of DriverManagerDataSource
along with connection pool feature.

Injecting EntityManager in DAO's for in-memory DB unit/integration testing?

I have a small Spring web application, with the typical MVC Service DAO JPA/Hibernate Persistence Layer architecture. In production, I use a JTA-like persistence unit. The DAO is injected with an instance of the EntityManager via #PersistenceContext by the container. All is fine.
Now, I want to test my DAO implementations using an in-memory database (outside of a container on my local pc). I could manually create a RESOURCE_LOCAL based EntityManager. But how can I have it injected in my DAO implementations automatically?
I have seen this question and it suggests that it is possible with Spring. But how?
Of course, for unit testing, I could use new MyDAOImpl() and inject the EntityManager myself, but later, I will want to test my services which are injected with DAO implementations. I would like to avoid having to wire everything myself... Is this possible?
In our project, we define a different unit-testing-config.xml that has the datasource bean defined to point the in-memory database as follows:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="org.hsqldb.jdbc.JDBCDriver" />
<property name="jdbcUrl"
value="jdbc:hsqldb:file:/data/data.db" />
<property name="user" value="sa" />
<property name="password" value="" />
<property name="initialPoolSize" value="1" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="240" />
<property name="checkoutTimeout" value="60000" />
<property name="acquireRetryAttempts" value="0" />
<property name="acquireRetryDelay" value="1000" />
<property name="numHelperThreads" value="1" />
</bean>
The normal entityManagerFactory defintion as follows will use the above datasource bean:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="myDoctorPersistenceUnit" />
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
</bean>
</property>
<property name="jpaDialect" ref="jpaDialect" />
</bean>
And we run our TestSuite using the following annotations:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations ={ "/spring-configuration/test-spring.xml" })
Hope this helps!

JDBC connection to Microsoft SQL Server doesn't reconnect

I have a database that is connected through an unreliable network connection to an application server, so occasionally the connections break down. Each time this happens, all database connections in the AP pool will need to reconnect - which they don't unfortunately.
I went through different setups of c3p0, dbcp and bonecp as pools and used JTDS as well as the SQL Server V3 driver, (I even ditched pooling atogether to try out whether the regular DataSource would be able to create a new unpooled connection - which it didn't) but all configuration variants don't seem able to recover after network failure.
To clarify, none of the DataSources were able to get a new Connection. Is there some inherent Problem with the MS Sql Server regarding reconnects? Am I missing something fundamental here?
I realize this might not be of big help, but just as an example this is the dbcp configuration
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.databaseurl}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriodInMinutes" value="1" />
<property name="idleMaxAgeInMinutes" value="1" />
<property name="maxConnectionsPerPartition" value="3" />
<property name="minConnectionsPerPartition" value="1" />
<property name="partitionCount" value="1" />
<property name="acquireIncrement" value="5" />
<property name="acquireRetryAttempts" value="50" />
<property name="acquireRetryDelayInMs" value="1000" />
<property name="queryExecuteTimeLimitInMs" value="5000" />
<property name="connectionTestStatement" value="SELECT count(*) FROM dbo.sysobjects" />
<property name="closeConnectionWatch" value="true" />
<property name="lazyInit" value="false" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>

Categories