Spring PropertyResourceConfigurer support for Bonecp DataSource - spring

I need to set the BoneCp driverProperties using Spring PropertyResourceConfigurer (setDriverProperties(Properties driverProperties). setDriverPropertie accepts java.util.Properties where I could pass the list of properties as key/values. Currently I am loading the DS using the applicationContext.xml with the help of PropertyPlaceholderConfigurer
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${database.driverClassName}" />
<property name="jdbcUrl" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
I am not sure how I can pass alist of custom properties using applicationContext.xml where BoneCPDataSource property name would be driverProperties which would be accepting java.util.Properties.

Related

Hibernate c3p0 and Spring. Invalid property 'driverClassName' of bean class [org.hibernate.c3p0.internal.C3P0ConnectionProvider]

I'm currently developing an application that uses hibernate and Spring MVC.
I want to implement c3p0 but I can't understand how to implement it.
I used the c3p0 jars in the optional folder, Hibernate-c3p0-5.0.2.jar and
c3p0-0.9.2.1.jar.
These are my configurations.
Right now, I'm using DriverManagerDatasource from Spring.
<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>
I tried doing this
<bean id="dataSource" class="org.hibernate.c3p0.internal.C3P0ConnectionProvider">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- C3P0 Config -->
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="100" />
<property name="hibernate.c3p0.max_size" value="10" />
<property name="hibernate.c3p0.max_statements" value="10" />
<property name="hibernate.c3p0.min_size" value="10" />
<property name="hibernate.c3p0.timeout" value="100" />
</bean>
but i'm getting an error.
Invalid property 'driverClassName' of bean class [org.hibernate.c3p0.internal.C3P0ConnectionProvider]
TIA.
driverClassName is a DriverManagerDataSource property, not a property on the C3P0ConnectionProvider. So that's why you're getting the error.
Instead of using the Spring DriverManagerDataSource, which is just a simple DataSource implementation and not a connection pool at all, you want to use C3P0's DataSource implementation. Try using ComboPooledDataSource. That implementation also has a driverClassName property, which you will want to set equal to your database driver (like MySQL driver or whatever).
Here's an example that I lifted off a web page:
cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver"); //loads the jdbc driver
cpds.setJdbcUrl("jdbc:mysql://localhost/test");
cpds.setUser("root");
cpds.setPassword("root");
That's not Spring, but just make the adjustment to put it in Spring. The full class name is com.mchange.v2.c3p0.ComboPooledDataSource. You can see a Spring-based example here.
i know this question is old but for the newbies, hope it helps.
The problem is with your name tags
replace:
<bean id="dataSource" class="org.hibernate.c3p0.internal.C3P0ConnectionProvider">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
with
<bean id="dataSource" class="org.hibernate.c3p0.internal.C3P0ConnectionProvider">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
...
Please note: driverClass is used instead of driverClassName, jdbcUrl is used instead of url, user is used instead of username and password is at it was..... these are the parameters for ComboPooledDataSource
HOPE IT HELPS

Can configure two DataSoure in a Spring configuration?

I am developing a web application and I need two DataSource to connect two difference database according to my requirement.One DataSource will use Spring + JPA framework and another DataSource is use Spring + MyBatis framework.
Yes you can I suggest manage both from spring and obtained from the applicationContext.
<bean class="org.apache.tomcat.jdbc.pool.DataSource" id="dataSource" >
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<bean class="org.apache.tomcat.jdbc.pool.DataSource" id="dataSourceOrderDetail" >
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url.orderdetail}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
Just need to have different name of id, to be properly injected
Check this to review how you can integrate spring with ibatis then configure beans using the datasource beans
Or if you want to use datasource-ds.xml just put the two datasource xml files in the lib folder within your application context, if you are using something like jboss or tomcat.
UPDATE
<jpa:repositories base-package="com.staples.sa.pricemart.repository.pag"
entity-manager-factory-ref="entityManagerFactory" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="pagTransactionManager" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<jpa:repositories base-package="com.staples.sa.pricemart.repository.orderdetail"
entity-manager-factory-ref="entityManagerFactoryOrderDetail" />
<bean id="transactionManagerOrderDetail" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryOrderDetail" />
<qualifier value="orderDetailTX" />
</bean>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactoryOrderDetail">
<property name="persistenceUnitName" value="persistenceUnitOrderDetail" />
<property name="dataSource" ref="dataSourceOrderDetail" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<!-- -->
Persistence.xml need to look like this. (need to complete the xml config)
<persistence-unit name="persistenceUnit"
transaction-type="RESOURCE_LOCAL">
And
<!-- Add the persistence context for OrderDetail -->
<persistence-unit name="persistenceUnitOrderDetail"
transaction-type="RESOURCE_LOCAL">
Here is the sample code for you
class Main {
public static void main(String args[]) throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("context.xml", Main.class);
DataSource dataSource = (DataSource) ac.getBean("dataSource");
DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource");
Context.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#oracle.devcake.co.uk:1521:INTL"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://dbhost-prospring-psql/prospring"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
<property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
</bean>
<bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
You can configure as many databases as you like in Spring context by declaring datasource beans with different id's and
injecting appropriate properties from properties file. if the two databases are different then you are in territory of distributed transactions and you must configure a Spring transaction manager which can operate with JTA. Also worth noting is that Spring transaction manager is merely an abstraction and it needs to have external JTA transaction
manager configured (like Bitrionix / Atomikos) or if deploying under EE application server then transaction manager can be looked up in JNDI registry. Then when you mark the transaction boundary (perhaps using Spring Transactional annotation) then Spring would automatically co-ordinate the transactions.

Dynamically (Runtime) change Datasource credentials in Spring Mybatis

I want to dynamically change Datasource properties in Spring+MyBatis project.
Problem is in Spring + MyBatis integration, we cannot set the datasource properties dynamically during runtime.
Currently I'm using the following code to set the credentials:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
I tried options with UserCredentialsDataSourceAdapter to change the password during runtime but I cannot return back the dataSource object to use for the connection as MyBatis
ApplicationContext context = ApplicationContextUtils.getApplicationContext();
UserCredentialsDataSourceAdapter ds = (UserCredentialsDataSourceAdapter) context.getBean("dataSource");
ds.setCredentialsForCurrentThread("test", "test");
I'm stuck here, I cannot use the dataSource element ds to use for making connection for MyBatis. Please help me in resolving this issue.
I suppose that you use mybatis-spring.
Your approach with UserCredentialsDataSourceAdapter is not working because you are using connection pool, so connection is not closed after usage but are returned to the pool and reused later even that you've changed username and password.
To fix this just get rid of pool:
<bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
<property name="targetDataSource" ref="targetDataSource"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
and use the later bean in SqlSessionFactoryBean configuration:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
If you do not use mybatis-spring and use mybatis directly then the problem is to make mybatis use configured DataSource. This can be done by registering dataSource in JNDI and configure mybatis to get DataSource from JNDI.
<bean id="targetDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${app.jdbc.driverClassName}" />
<property name="url" value="${app.jdbc.url}" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
<property name="targetDataSource" ref="targetDataSource" />
<property name="username" value="#{app.jdbc.username}" />
<property name="password" value="#{app.jdbc.password}" />
</bean>
<!-- Declare a transaction manager for Encounter Navigator Authenticator -->
<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- define the SqlSessionFactory for Encounter Navigator Authenticator,
notice that configLocation is not needed when you use MapperFactoryBean -->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
name="sqlSessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations"
value="file:C:/Program Files/Apache Software Foundation/Tomcat 7.0/config/app_user/*.xml" />
<property name="configLocation" value="classpath:sqlmap-config.xml" />
</bean>
<!-- scan for MAPPERS and let them be auto-wired - For Encounter Navigator
Authenticator -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="com.upmc.health.encounternavigator.dao.authentication" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
UserCredentialsDataSourceAdapter ds = (UserCredentialsDataSourceAdapter) applicationContext.getBean("dataSource");
ds.removeCredentialsFromCurrentThread();
ds.setCredentialsForCurrentThread("test", "test");
ds.setUsername("test");
ds.setPassword("test");
ds.setTargetDataSource(ds);
ds.afterPropertiesSet();
authDao.getDetails(); //This calls an interface and executes the query present in the xml file

How to get spring bean reference to java field automatically

my spring XML is below,
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="jTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
I'm creating the spring bean context when the server is starting up. When I hit on the submit button of the JSP page, it should call the servlet and executes the SQL Query.
Without doing JdbcTemplate jTemplate = (JdbcTemplate)context.getBean("jTemplate") is there anyway I can get the jTemplate object automatically injected to my java property?
my java property is this,
private JdbcTemplate jTemplate;
So, simply I want to use the jTemplate without just doing JdbcTemplate jTemplate = (JdbcTemplate)context.getBean("jTemplate")
Sorry guys I'm bit new to Spring, If you don't get what I'm saying please ask me again.
Use autowiring which can be in three ways
By name
By Type
By Constructor
Further reading is available here
like one solution is
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" autowire="byName">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean name="jTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
Use #Autowired annotation to get this bean automatically like this.
#Autowired
private JdbcTemplate jTemplate;

How to Define a MySql datasource bean via XML in Spring

I've looked over the documentation to define a bean. I'm just unclear on what class file to use for a Mysql database. Can anyone fill in the bean definition below?
<bean name="dataSource" class="">
<property name="driverClassName" value="" />
<property name="url" value="mysql://localhost/GameManager" />
<property name="username" value="gamemanagertest" />
<property name="password" value="1" />
</bean>
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/GameManager" />
<property name="username" value="gamemanagertest" />
<property name="password" value="1" />
</bean>
http://docs.spring.io/spring-data/jdbc/docs/1.1.0.M1/reference/html/orcl.datasource.html
Use this class org.springframework.jdbc.datasource.DriverManagerDataSource - DriverManagerDataSource. As a best practice its better if we isolate the database values into a .properties file and configure it into our spring servlet xml configuration. In the below example the properties are stored as key-value pairs and we access the value using the corresponding key.
applicationContext-dataSource.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" 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}"/>
<property name="connectionCachingEnabled" value="true"/>
</bean>
<context:property-placeholder location="classpath:jdbc.properties"/>
jdbc.propeties file:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sample_db
jdbc.username=root
jdbc.password=sec3ret
Both the answers are appropriate for the question. But just for an FYI if you're going to use DriverManagerDataSource as your datasource, every call to your datasource bean will create a new connection to your database which is not recommended for production and even it does not pool connections.
If you need a connection pool, consider Apache Commons DBCP.
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/GameManager" />
<property name="username" value="gamemanagertest" />
<property name="password" value="1" />
<property name="initialSize" value="2" />
<property name="maxActive" value="5" />
</bean>
Where initialSize and maxActive are pooling related properties.
To use this make sure you have the required jar in your path.

Resources