Load Spring Database Properties from Tomcat's lib dir - spring

I want to put the property file with database connection string in the lib directory of Tomcat and load this file for datasource in Spring XML definition. Is there a way to do this? (because I know how to load from the classpath).

Yes this is perfectly possible as files available in tomcat lib are available under classpath to web app. we are using this already in project.
<util:properties id="appConfig" location="classpath:app.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="#{appConfig['app.db.url']}" />
<property name="username" value="#{appConfig['app.db.user']}" />
<property name="password" value="#{appConfig['app.db.password']}" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="minEvictableIdleTimeMillis" value="60000"></property>
<property name="validationQuery" value="SELECT 1" />
</bean>

Related

Spring JDBC Extensions, Oracle AQ, ClassCastException on listening to queue

(I hope this below makes sense, I had a bit of a struggle with formatting).
We have an application (currently being refreshed from technology of circa 2005) whose owners require the use of Oracle AQ for message handling.
We are using the Spring JDBC extensions, and when the application begins to listen to the queue it gets a ClassCastException saying "X cannot be cast to oracle.jdbc.internal.OracleConnection".
Where X is either a WrappedConnectionJDK7 from jboss when we use a datasource defined in Wildfly e.g.
<bean id="dataSource-supsrep"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE" />
<property name="username" value="...." />
<property name="password" value="...." />
</bean>
or X is a PoolGuardConnectionWrapper from commons.dbcp when we define the datasource like this:
<bean id="dataSource-supsrep"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE" />
<property name="username" value="...." />
<property name="password" value="...." />
</bean>
Message Listener bean is defined like this :
<bean id="messageListener" class="xxx.report.dispatch.DispatchMDB" />
Message Listener container bean is like this :
<bean id="reportProcessorXslfoHigh"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="sessionTransacted" value="true" />
<property name="connectionFactory" ref="AQconnectionFactory" />
<property name="destinationName" value="Q1_XSLFO_HIGH" />
<property name="messageListener" ref="messageListener" />
<property name="transactionManager" ref="transactionManager" />
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="1" />
<property name="receiveTimeout" value="30000" />
<property name="idleTaskExecutionLimit" value="30" />
<property name="idleConsumerLimit" value="1" />
</bean>
The connection factory is like this :
<orcl:aq-jms-connection-factory id="AQconnectionFactory"
data-source="dataSource-supsrep" native-jdbc- extractor="oracleNativeJdbcExtractor" />
and it uses a Native JDBC Extractor :
<bean id="oracleNativeJdbcExtractor"
class="org.springframework.jdbc.support
.nativejdbc.OracleJdbc4NativeJdbcExtractor" />
So my question is - can this be overcome by Spring configuration details - or is there another way round it? Clearly the underlying connection is needed but after 3 days of research I cannot see how it can be done.
Any clues gratefully received !
Thanks,
John

Multiple database Schema with Spring+Hibernate+JPA

I have same database schema database_1 and database_2 and want to configuration of these two database(database schema is same) and decide run time which database is use.
My persistence.xml is as below:
<persistence-unit name="first" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.model.AboutUs</class>
<class>com.model.AccessCards</class>
<properties>
<property name="hibernate.dialect" value="com.util.customMySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
<property name="hibernate.jdbc.batch_size" value="20"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
</properties>
</persistence-unit>
Persistence name second configure here as below :
<persistence-unit name="second" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.model.AboutUs</class>
<class>com.model.AccessCards</class>
<properties>
<property name="hibernate.dialect" value="com.util.customMySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
<property name="hibernate.jdbc.batch_size" value="20"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
</properties>
</persistence-unit>
Both persistence units load same classes .
and now my database-configure.xml as where i configure persistence unit with data source. as below first persistence unit name configare with datasource name datasource as :
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="first" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${datasource.driverClassName}" />
<property name="jdbcUrl" value="${datasource.url}" />
<property name="user" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="acquireIncrement" value="1" />
<property name="acquireRetryAttempts" value="1" />
<property name="maxIdleTime" value="300" />
<property name="maxPoolSize" value="20" />
<property name="minPoolSize" value="3" />
<property name="maxStatements" value="300" />
<property name="testConnectionOnCheckin" value="true" />
</bean>
Now this code for configure second persistence unit name with data source name datasource5 as below :
<bean id="transactionManager5" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory5" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource5" />
<property name="persistenceUnitName" value="second" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="dataSource5" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${datasource.driverClassName}" />
<property name="jdbcUrl" value="${datasource5.url}" />
<property name="user" value="${datasource5.username}" />
<property name="password" value="${datasource5.password}" />
<property name="acquireIncrement" value="1" />
<property name="acquireRetryAttempts" value="1" />
<property name="maxIdleTime" value="300" />
<property name="maxPoolSize" value="20" />
<property name="minPoolSize" value="3" />
<property name="maxStatements" value="300" />
<property name="testConnectionOnCheckin" value="true" />
</bean>
Now i use entity manager for save data in database and i am using mysql database . I got entity manager with persistence unit name first and second .
#PersistenceContext(unitName="first")
private EntityManager entityManager;
#PersistenceContext(unitName="second")
private EntityManager entityManager2;
Now entity manager save data in database using persist( object) method successfully .
entityManager.persist(project);
and entityManager2 save data in database using persist( object ) method successfully (No Exception here). But data does not store in database datbase_2 .
entityManager2.persist(project);
If I change the order of persistence unit first and second in persistence.xml then entityManager2 save data in database and entitymanager does not save data in database .
Any one have idea how i can make multiple entitymanager for same database schema .
There are a few limitations:
#Transactional corresponds to single TransactionManager.
JpaTransactionManager corresponds to single EntityManager(Factory).
Thus use separate methods with #Transactional annotation for each transaction manager:
#Transactional(transactionManager = "tmBeanName")
After that entity managers will work fine.
Also, some workaround exists to break the second limitation (DO NOT USE IT in this case):
It is possible to use single JtaTransactionManager instead of several JpaTransactionManager: distributed transaction will cover both entity managers and they will work fine too.

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

Mule to JPA compatibility

I using Mule Studio version: 1.3.1 .
buildDate: 201209061215
I am not able to get JPA end point. I also downloaded jpa-connector-1.0-20120925-2201.jar
But I dont know to to integrate with mule studio.
So I decided to use a simple Java transformer and write my processing logic which will be internally using JPA/Hibernate.
I came to know that i have to use a JPA vendor adapter for spring, else none of my service, DAO classes will be instantiated.
I have declared a datasource and entityManager as beans of spring inside mule flow xml as shown.
<spring:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<spring:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<spring:property name="url" value="jdbc:mysql://localhost:3306/eigDB" />
<spring:property name="username" value="root" />
<spring:property name="password" value="tiger" />
</spring:bean>
<spring:bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<spring:property name="dataSource" ref="dataSource" />
<spring:property name="persistenceUnitName" value="autoRebateSystem" />
<spring:property name="jpaVendorAdapter">
<spring:bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<spring:property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<spring:property name="showSql" value="true" />
</spring:bean>
But mule flow xml is not able to recognize any class of spring framework.
Finding very difficult to replace those class names.
Plez provide the solution for my problem,
By letting me know the PROPER replacements for mule studio.
1) org.springframework.jdbc.datasource.DriverManagerDataSource
2) org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
3) org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
Are you missing to use HibernateJpaDialect and JpaTransactionManager;
I hope the following configuration will be useful.
<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/yourdatabase"/>
<property name="username" value="your- username"/>
<property name="password" value="your- password"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--<property name="dataSource" ref="dataSource"/>-->
<property name="persistenceUnitName" value="<your-persistunit-name>"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect/>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver">
</bean>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/>
<!-- <property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" />-->
<property name="generateDdl" value="false"/>
<property name="showSql" value="false"/>
</bean>
To integrate it within MuleStudio, please add this update site within MuleStudio:
http://tecnologia.2020mobile.es/jpa-cloud-connector/update-site/

Can I use multiple C3P0 datasources for DB instance?

I was wondering if I can run multiple c3p0 datasources for one DB, something like:
<bean id="dataSource1" class = "com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${db.driverClassName}"/>
<property name="jdbcUrl" value="${db.url}/schema1"/>
<property name="user" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="acquireIncrement" value="1" />
<property name="idleConnectionTestPeriod" value="100"/>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="1800" />
</bean>
<bean id="dataSource2" class = "com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${db.driverClassName}"/>
<property name="jdbcUrl" value="${db.url}/schema2"/>
<property name="user" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="acquireIncrement" value="1" />
<property name="idleConnectionTestPeriod" value="100"/>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="1800" />
</bean>
They will be used by difference persistence services.
Thanks.
That's absolutely fine. You'll run into some configuration issues like:
autowiring DataSource by type won't work
#Transactional/declarative transactions will work only against one, selected DataSource. Alternatively you'll have to manually tell which transaction manager you want to use (thus you'll need two transaction managers as well: transactionManager1 and transactionManager2):
#Transactional("transactionalManager2")
Besides, there's nothing wrong with this configuration. Actually it's a pretty good idea (+1): if some layers/components of your application saturate the pool, others can still operate.
The only thing I recommend is to use lesser known abstract/parent bean declarations to avoid repetition:
<bean id="dataSource" abstract="true" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${db.driverClassName}"/>
<property name="user" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="acquireIncrement" value="1" />
<property name="idleConnectionTestPeriod" value="100"/>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="1800" />
</bean>
<bean id="dataSource1" parent="dataSource">
<property name="jdbcUrl" value="${db.url}/schema1"/>
</bean>
<bean id="dataSource2" parent="dataSource">
<property name="jdbcUrl" value="${db.url}/schema2"/>
</bean>
See also:
What is meant by abstract="true" in spring?

Resources