Spring JdbcTemplate ConnectionPooling Configuration - spring

I am working on a Spring MVC application in which I have recently been convinced to revamp my database code. Before I was using very traditional JDBC code that I have been told was very "old school" because of the boilerplate code. I have been making the transition to using JdbcTemplate with Spring.
I have configured a bean like shown below in my applicationContext.xml file.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:ip-address:port/dbName"/>
<property name="username" value="myUsername"/>
<property name="password" value="mypassword"/>
</bean>
I have run tests just to make sure everything is working and it is.
My question is, I am aware that I am using the Commons DBCP package which uses the
following packages
commons-dbcp package
commons-pool package
Again, I am very inexperienced with this, so I apologize if I am mis referencing something or am explaining something incorrectly.
I have followed what most of the tutorials have said to do and specified a jdbcTemplate and injected the dataSource bean into it, but this doesnt really refer to my question.
What I would really like to know is, am I using ConnectionPooling with this configuration?
If so, is it being done behind the scenes, or do I need to specify to do it somewhere?
I have looked at the documentation at Here which gives the following, but I am not sure exactly how to interpret it.
"here are several Database Connection Pools already available, both within Apache products and elsewhere. This Commons package provides an opportunity to coordinate the efforts required to create and maintain an efficient, feature-rich package under the ASF license.
The commons-dbcp package relies on code in the commons-pool package to provide the underlying object pool mechanisms that it utilizes."
I also looked at the Configuration Page
and based on this page, I would think that I am able to do ConnectionPooling, but may need to specify additional parameters in my dataSource bean.
Can somebody please answer my questions or point me in the right direction?

Yes you are using connection pooling.
here is another thread you might find interesting
http://forum.springsource.org/showthread.php?t=40598
Also most of the links you specified above will provide additional information on parameters that can be set.

Related

Programatically set v$session program property

I found some answers on the problem but none that i could make work in my case. My problem is that I load a datasource from my JBoss configuration with spring:
<xa-datasource jndi-name="java:jboss/jdbc/oracleDatasource" pool-name="jdbc/oracleDatasource" enabled="true">
<xa-datasource-property name="URL">
jdbc:oracle:thin:#URL:1522:SID
</xa-datasource-property>
<xa-datasource-property name="connectionProperties">
v$session.program=MyAPP
</xa-datasource-property>
<driver>oracle-jdbc</driver>
The spring loading is made as follows:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/jdbc/oracleDatasource"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
As you can see, I have set the v$session.program property in JBoss, it works well.
The problem is that i have several applications (war) that can be deployed on the same JBoss server, using this configuration. What I want to do in this case is to have each of my application to have its own name written in the v$session.program property.
So basically, i would like to be able to load the same datasource on each app but to have each of them using its own name to log the program property in oracle DB. Is it possible or do I have to have one datasource for each application hosted?
The only thing you need it to intercept each call of getConnection from connection pool.
You must obtain a real Oracle connection - not a proxy - and call the setClientInfo on 12c or setEndToEndMetrics in older versions to set the action / client / module identification.
An example see here.
Also note that the use of dbms_application_info for this same purpose works as well, but this produces a one server roundtrip too much. The setClientInfo doesn't produce server call, but stores this information for the next statement execution (which is the preformance saving approach).
Also note that to use this feature, your driver must match perfectly with your database - the strange exeptions you can see while setting teh client info are in most cases caused by the incompatibility of teh JDBC driver and the RDBMS.
If putting this information into v$session.module or v$session.client_info is an option, you can do using Java code.
All you need to do is call dbms_application_info.set_module() or dbms_application_info.set_client_info() after your Java code obtained the connection from the datasource.
Something like this:
Connection conn = ... // get connection from the DataSource
CallableStatement cstmt = conn.prepareCall("{call dbms_application_info.set_client_info(?)}");
cstmt.setString(1, "Some interesting information");
cstmt.execute();

Hibernate changes database change

I am using Struts and Hibernate 2.0 in my project. My database has changed from oracle 10g to Oracle 11g in my project.
Can you please tell me what changes do I need to make in my Hibernate configuration?
Also Are there any changes required in my Java code.
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:#<host>:<port>:<sid></property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.show_sql">false</property>
</session-factory>
</hibernate-configuration>
Just update driver (Jar file) to Oracle Database 11g Release 2 JDBC Drivers
Your XML doesn't seem like it was configured to Oracle 10g , it shows MySQL..
Anyways do this to solve your question.
Just change the Driver name and URL i.e connection string and also change the Dialect
search for Oracle Dialect online and don't forget to add Jars!!! :)
If your data access logic is implemented in Hibernate then your code is portable. Meaning you really don’t need to change anything specific to database change in your case apart from Driver if its causing any trouble . For instance, if you are changing database from MYSQL to Oracle then probably need to change dialect part, Connection properties of your hibernate configuration file alone plus your database specific driver.
Hope this is helpful!
Yes you need to change the dialect name. Sorry I am posting another answer as I am not able to add another comment.
Find for Oracle11g dialect name online, Dialects are classes that convert HQL(hibernate query language to actually Database query), it may say ClassNotFoundException, if this happens then just search for the Hibernate jar that has Oracle11g Dialect Class in it. As I am pretty sure that this jar is NOT available with the JDBCDriver jars that ORacle provides to connect to database.
The Dialect Jars are a part of Hibernate

Spring #Cacheable not working - what's wrong with my config?

I've seen many incarnations of this same issue but I think I've tried all the fixes - my usage is quite straightforward.
I had been using Ehcache which also didn't work. So, to rule out Ehcache issues and help point to something more fundamental, I moved to SimpleCacheManager and ConcurrentMapCacheFactoryBean.
Here's my config:
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="parentAppIds"/>
</set>
</property>
</bean>
Here's my method:
#Cacheable(value="parentAppIds", key="accountNumber")
public Long findApplicationId(String accountNsc, String accountNumber) throws EMSException {
....
}
This is a method on an interface, who's implementing class is Spring managed #Service("foo")
I tried using 'p0' as is suggested here but to no avail. I have no compilation problems and no errors in my server logs so I'm confident that I have all that is necessary on my classpath; and that Namespaces are all fine, since I'm using STS for that - so I left out pom.xml and spring Namespace declarations to block noise.
I'm using Spring 3.1; Java 1.5 and Websphere 6.1
The symptom is that the method is being visited with the same parameters repeatedly.
Please help - I'm hungry and refuse to go for lunch until I nail this.
note: I have simplified my #Cacheable declaration my actual one is
#Cacheable(value="parentAppIds", key="#p0.concat('-').concat(#p1)")
Neither work.
Thanks.
** Edit - I've ruled out Websphere as being a problem by creating a test rig with
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(...)
which mimics what is happening. #Cacheable is simply not working. There must be something blindingly obvious that I am missing. (I've had lunch now)
My issue is resolved. Unfortunately I cannot pinpoint exactly where my issue lay. Certainly, all that is required is that which I have mentioned in my question.
TO fix this, I tidied up my Spring configuration a bit and cleared my browser and application server cache and temp directories. I did a full clean install and cache is now working.
It is possible that I was testing with an earlier version which did not include this important line in the application config:
<cache:annotation-driven/>
I had omitted that at the start. Maybe my adding of that was not picked up until now. Otherwise I am stumped. Thanks for your time.
Did you perhaps change
#Cacheable(value="parentAppIds", key="accountNumber")
to
#Cacheable(value="parentAppIds", key="#accountNumber")
as adding the # that removed one error for me while trying to get caching working.

Where to store database passwords in a spring application or use JNDI?

Seems like a simple task. I have a webapp which requires a database connection. I'd like to be able to drop an updated .war file on this app server and load a new version without having to re-edit an applicationConfig.xml file to specify the database connection parameters for production.
Is using the container to setup the data source and then referencing it from JNDI the preferred way to go? I think it is cleaner having it all defined in the spring .xml file, but I can't come up with a clean way to allow the production password to be set only once as we roll out new versions.
So, how do you specify your database connection information in a spring application so that you can upgrade it without having to re-edit the files?
If you use JNDI, how do you handle setting up of your tests since the JNDI is not going to be available outside of the container?
Thanks!
The typical way to externalize database connection properties is to store them in a .properties file and load using <context:property-placeholder .../> . Then you can have different .properties files for testing and production.
If you choose JNDI, you can use a Spring's mock JNDI support for testing.
One approach is for your Spring configuration file to be composed of fragments related to specific layers in your application.
One such fragment could contain your DataSource defintion. For production, this fragment would use a jee:jndi-lookup. And then for test, have a different fragment would use a DriverManagerDataSource ?
Update:
If you want to change the datasource after deployment, then you can use this technique, along with changing the which datasource is injected into your other beans using a PropertyPlaceholderConfigurer as explained in an old post I wrote
eg:
<bean class="foo.bar.SomeClassNeedingDataSource"">
<property name="dataSource" ref="${the.datasource.to.inject}" />
</bean>
<jee:jndi-lookup id="jndiDataSource" ... />
<bean id="driverManagerDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
# the properties file
the.datasource.to.inject = jndiDataSource
#the.datasource.to.inject = driverManagerDataSource

why is jax-ws spring service reference prefixed with #, as in ws:service bean="#myService"

I've developed a web service with jax-ws and Spring using the tutorials at the jax-ws commons website. It shows you how to define and reference your service from your spring applicationContext file (https://jax-ws-commons.dev.java.net/spring/).
What is the reason for the "#" when referencing the web service? I would expect to see something more like
<ws:service name="myEventWS" ref="eventWebService"/>
but following example at the above link I created the following which works.
<bean id="eventWebService" class="com.myws.EventWS">
<property name="model" ref="EventModel"/>
</bean>
<wss:binding url="/EventWS">
<wss:service>
<ws:service bean="#eventWebService"/>
</wss:service>
</wss:binding>
<ws:service> is using a custom configuration namespace, which is a feature of Spring which allow you to express complex bean graphs using simpler namespace. The meaning and interpretation of these custom namespaces is down to the implementation in question, in this case the JAX-WS-Commons project. It seems the authors of that decided that bean=#eventWebService means what you refer to as ref="eventWebService".
I don't know whay they did it that way, maybe they thought it was more readable... maybe they thought that bean=eventWebService (without the hash) means a name, rather than a reference... I don't know. The documentation isn't very clear either.
Either way, I'm pretty sure sure it's not a core Spring syntax, nor a convention that I've seen before.
the "#" tells the bean that it's not a class, but rather a ref.
HTH
#eventWebService refers to the bean of type EventWebService (according to the default Spring naming convention when bean is is not specified).

Resources