Quartz Cron scheduler in Spring with jdbc store - java

I need to create Cron service in Spring, but I can not find enough info how to do it with jdbc store. I want Quartz to use my present connection to Datasource, my database is PostgreSql. I need to create use jdbc store, because task should be done even if server was down.

You can try something like this
<bean id="scheduler-JDBC" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" abstract="true">
<property name="dataSource" ref="myDataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="jobFactory">
<bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
</property>
<property name="overwriteExistingJobs" value="true" />
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.isClustered">false</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
</props>
</property>
</bean>
<bean id="cronScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" parent="scheduler-JDBC">
<property name="startupDelay" value="10" />
<property name="autoStartup" value="true" />
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="triggers">
<list>
<ref bean="myTrigger" />
</list>
</property>
</bean>
Download Quartz distribution from http://quartz-scheduler.org/ and you will find the database script for needed tables in docs/dbTables.

Related

connecting to databases using spring and hibernate - primary and secondary databases

Hi this is what I am looking to do -
I have three databases - each exactly the same - one is primary and two and three are back ups.
I am using hibernate and spring to connect to the data base.I have spring application context file configured with 3 session factories, and 3 corresponding data sources.
I was wondering if there is a way using spring where if the application is not able to connect to the database 1 (an exception is thrown) it will connect to database 2 - and in turn is database 3 is down it will connect to 3 and proceed.
What would be the best way to implement this? I have read about AbstractRoutingDataSource ..but not sure how to make use of that in this case..also if there are other ideas.. Would appreciate some directions. Thanks!
this is my config in application context xml -
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url1}" />
<property name="user" value="$l{uid1}" />
<property name="password" value="$l{pwd1}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory1"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url2}" />
<property name="user" value="$l{uid2}" />
<property name="password" value="$l{pwd2}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="$g{jdbc.driverClassName}" />
<property name="jdbcUrl" value="$g{url3}" />
<property name="user" value="$l{uid3}" />
<property name="password" value="$l{pwd3}" />
<property name="minPoolSize" value="$g{jdbc.minPoolSize}" />
<property name="maxPoolSize" value="$g{jdbc.maxPoolSize}" />
<property name="preferredTestQuery" value="$g{jdbc.preferredTestQuery}" />
<property name="testConnectionOnCheckout" value="$g{jdbc.testConnectionOnCheckout}" />
</bean>
<bean id="sessionFactory3"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource3" />
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">$g{jdbc.dialect}</prop>
<prop key="hibernate.show_sql">$g{jdbc.show_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager1"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory1" />
</bean>
<bean id="transactionManager2"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2" />
</bean>
<bean id="transactionManager3"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory3" />
</bean>
There is a way to achieve this by using Spring Abstract Data Source Routing mechanism -
https://spring.io/blog/2007/01/23/dynamic-datasource-routing/

Configure hibernate in spring application

I have successfully configured hibernate and I can run transactions but only from the psvm of the DAO class. I want to configure it with my spring app using the same configuration file i.e. hibernate.cfg.xml.
How can I do this? Most tutorials I've read simply neglect the hibernate configuration file.
You can add this code to you xml file to configure hibernate.
<!-- Hibernate Related Configuration. -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://192.168.1.9:5432/dbname"/>
<property name="username" value="postgres"/>
<property name="password" value="pwd"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.domain"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
The hibernate.cfg.xml file is specified for the LocalEntityManagerFactoryBean, along with your DataSource
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/hibernate.cfg.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
Here you can find an example of a Spring XML configuration containing some Hibernate configuration

Configuring properties via datasource vs configuring them via hibernateProperties

What is the difference between using datasource and using hibernateProperties. I want to use c3P0 with spring in my app. I found 2 ways to do so but I'm unable to understand the difference between the two
First:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
depends-on="dataSource">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
</props>
</property>
<bean id="dataSource" destroy-method="close"
class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="maxPoolSize" value="10" />
<property name="numHelperThreads" value="5" />
</bean>
Second:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
>
<property name="hibernateProperties">
<props>
<property name="hibernate.c3p0.maxSize" value="100" />
<property name="hibernate.c3p0.numHelperThreads" value="5" />>
</props>
</property>
</bean>
The first you get a Spring managed datasource, which you can also use for a JdbcTemplate or other work.
The second you get a hibernate managed datasource which is not reusable by Spring.
I strongly suggest the first approach as it also makes it quite easy to replace your datasource for testing (by replacing it with an in-memory database) or to replace it with a JNDI lookup.

Where to place c3p0 properties in configuration file?

I am using spring/hibernate integrated application. i have configured c3p0 connection pooling. the problem is if i set c3p0 properties in hibernate properties section then those properties are not considered and default configuration is taken. if i set the same properties for combopooled datasource then they are considered. where is the best place to place c3p0 properties.
Below configuration works:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClassName}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
<!-- c3p0 properties -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxStatements" value="0" />
<property name="preferredTestQuery" value="select * from sometable" />
</bean>
<bean name="wygSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations" value="classpath:hibernate/module/*.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.pool.size">20</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
This does not work:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClassName}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean name="wygSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations" value="classpath:hibernate/module/*.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.pool.size">20</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!-- c3p0 properties -->
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">select * from sometable</prop>
</props>
</property>
</bean>
I was getting the same problem and it took time to figure out the solution.
I use Hibernate 4.0.1 and mysql 5.1(no spring framework) and I was facing the issue. First make sure that you configured the c3p0 jars properly which are essential.
I used these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<property name="hibernate.c3p0.idle_test_period">10</property>
<property name="hibernate.c3p0.acquireRetryAttempts">5</property>
<property name="hibernate.c3p0.acquireRetryDelay">200</property>
<property name="hibernate.c3p0.timeout">40</property>
But it's of no use 'cause C3p0 was still taking the default properties not the properties which I set in hibernate.cfg.xml, You can check it in logs. So, I searched many websites for right solution and finally I came up with this. remove the C3p0 properties in cfg.xml and create c3p0-config.xml in the root path(along with cfg.xml) and set properties as follows.
<c3p0-config>
<default-config>
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">40</property>
<property name="idleConnectionTestPeriod">10</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
<property name="maxStatements">50</property>
<property name="preferredTestQuery">SELECT 1;</property>
<property name="acquireRetryAttempts">5</property>
<property name="acquireRetryDelay">200</property>
<property name="maxIdleTime">30</property>
</default-config>
</c3p0-config>
but if you run, ORM takes the jdbc connection but not C3p0 connection pool 'cause we should add these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
now everything works fine(At least it worked fine for me) and the issue is solved.
check the following for references.
http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing
https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool
I hope this solves your problem.

How to set the name of the net.sf.ehcache.CacheManager for JMX monitoring?

I am using EhCache 1.4.0, Spring 3.0.5 in a web application deployed on Tomcat 6 using JRE 1.6. I am exposing via JMX the L2 cache management, like this:
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<util:property-path id="hibernateCacheProvider" path="sessionFactory.settings.cacheProvider" />
<bean id="hibernateEhCacheManager" class="com.mycompany.spring.beans.factory.config.UnaccessibleFieldRetrievingFactoryBean">
<property name="targetObject" ref="hibernateCacheProvider" />
<property name="targetField" value="manager" />
<property name="makeInstanceFieldVisible" value="true" />
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<description>The cacheManager configuration.</description>
<property name="targetClass" value="net.sf.ehcache.management.ManagementService" />
<property name="staticMethod" value="net.sf.ehcache.management.ManagementService.registerMBeans" />
<property name="arguments">
<list>
<ref bean="hibernateEhCacheManager" />
<ref bean="mbeanServer" />
<value type="boolean">true</value>
<value type="boolean">true</value>
<value type="boolean">true</value>
<value type="boolean">true</value>
</list>
</property>
</bean>
<bean class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter">
<property name="server" ref="mbeanServer" />
<property name="beans">
<map>
<entry key="Hibernate:type=statistics,application=applicationOne">
<bean class="org.hibernate.jmx.StatisticsService">
<property name="statisticsEnabled" value="true" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</entry>
</map>
</property>
</bean>
<bean id="hbm.properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">applicationOne-web/ehcache.xml</prop>
<prop key="hibernate.cache.query_cache_factory">org.hibernate.cache.StandardQueryCacheFactory</prop>
</props>
</property>
</bean>
I have to allow to clear all the entries in the L2 cache by using the jmxterm tool, like this:
run --bean net.sf.ehcache:type=CacheManager,name=net.sf.ehcache.CacheManager#605df3c5 clearAll
I am aware of jconsole to determine the exact CacheManager, from the context, but I may not use it for some reasons I won't get into.
So far, so good, but suppose that my JVM (Tomcat server) has 2 applications deployed, both allowing JMX monitoring for EhCache. The names of these two MBeans will be:
net.sf.ehcache:type=CacheManager,name=net.sf.ehcache.CacheManager#605df3c5
net.sf.ehcache:type=CacheManager,name=net.sf.ehcache.CacheManager#49ff3459
As you can see they are not quite useful when trying to determine which cache to clear.
So my question is: is there any possibility to set the name of each CacheManager, in order to identify exactly which one to use to clear all the entries in the L2 cache ?
Thank you.
I know this was answered long ago, but I think it is easier just to set it in your ehcache configuration file (applicationOne-web/ehcache.xml).
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
monitoring="autodetect" dynamicConfig="true" name="MY_CACHE_MANAGER_NAME">
...
</ehcache>
Once the hibernateEhCacheManager is available one can invoke its methods (setting the including) using the following bean definition. Normally this should do the trick renaming the CacheManager.
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref local="hibernateEhCacheManager"/>
</property>
<property name="targetMethod">
<value>setName</value>
</property>
<property name="arguments" value="<the_desired_name>"/>
</bean>

Categories