Spring,Quartz and JobStoreTX - spring

By using CronTriggerBean i have created two triggers(say trigger A & B) for invoking two different action. We have placed our project as .war in 2 servers.I am using JobStoreTX for clustering. The problem i am facing is that i want to cluster only one trigger i.e A and trigger B should not be clustered. Is there a way to specify through code which trigger has to be clustered. My code goes on as below.
<bean id="shedulerJobStoreTX" class="org.quartz.impl.jdbcjobstore.JobStoreTX>
<property name="driverDelegateClass" value="org.quartz.impl. jdbcjobstore.oracle.OracleDelegate">
<property name="dataSource" value ="jndiDS"/>
<property name="tablePrefix" value="someschemaName"/>
<property name="isClustered" value="true"/>
<property name="clusterCheckinInterval" value="${someValue}"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="clusterCronTrigger"/>
</list>
</property>
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="runAppJob" />
<property name="cronExpression" value="${someTimeValue1}"/>
</bean>
<bean id="clusterCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="runClusterJob" />
<property name="cronExpression" value="${someTimeValue2}"/>
</bean>
Hi, I have refined the code and the above said issue is not happening.PFB the code for the same.
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="clusterCronTrigger"/>
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.isClustered">false</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key ="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.
JobStoreTX </prop>
<prop key="org.quartz.jobStore.tablePrefix">schemaName</prop>
<prop key="org.quartz.jobStore.driverDelegateClass"> org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>
<prop key="org.quartz.jobStore.selectWithLockSQL"> SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME= ?</prop>
</props>
</property>
<property name="dataSource" ref="fsmJndiDataSource"/>
But the problem on executing the above code is that i am getting the below exception when the quartz is trying to get the lock ..."Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view does not exist"

you need to create required quartz tables in database before you run scheduler.
default quartz tables sql script is available at \docs\dbTables..
example if you are using quartz 2.2.1 distribution (quartz-2.2.1-distribution.tar\quartz-2.2.1\docs\dbTables\tables_oracle)
execute the sql script on database and make sure you see the tables created in it refer below image

Due to the message "ORA-00942: table or view does not exist", I think the table "schemaNameLOCKS" is missing. Indeed, from the doc:
org.quartz.jobStore.selectWithLockSQL
Must be a SQL string that selects a row in the "LOCKS" table and
places a lock on the row. If not set, the default is "SELECT * FROM
{0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE", which
works for most databases. The "{0}" is replaced during run-time with
the TABLE_PREFIX that you configured above. The "{1}" is replaced with
the scheduler's name.

Related

spring bean optional property

I am using a data source defined in tomcat in my spring configuration as shown in the below xml.
It can happen sometimes that this data source may not be defined in the context.xml of tomcat.
In such cases , the context initialization fails since myDS is not found.
Is it possible to configure the datasource as optional so that application initialisation is not impacted ?
There can be a run time error when this data source is accessed , which is acceptable
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myDS"/>
</bean>
<bean id="myEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="packagesToScan" value="com..XX.XX" />
<property name="persistenceUnitName" value="myPU" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="#{systemProperties['showSql'] == null ? 'true' : systemProperties['showSql'] }" />
</bean>
</property>
<property name="persistenceUnitPostProcessors">
<list>
<ref bean="wrkflw-punitpostprocessor" />
</list>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">#{systemProperties['dbDialect']}</prop>
</props>
</property>
</bean>
Thanks
Muhad
You may check the DelegatingDataSource, you could encapsulate the logic to load the datasource from JNDI within its instantiation. For your application there will be always a DataSource there, but in some cases (whenever its not able to load the DataSource from JNDI) there is no delegation.

Spring and H2 or Derby - Multiple Transactions

I have a project that uses Spring. In local environment I use Derby (with Jetty) that gives me the perfomance that I need in this environemnt (in production is used Oracle and Weblogic).
The problem is that I need new transactions in some specific operations. This specific operations use the annotation #Transactional(propagation=REQUIRES_NEW).
The problem is that with Derby when comes the time that a new transaction was supposed to be createad, the operation hangs and due time out. I tried to use H2 but in the same moment of creation of the new transaction, the database is restarted, meaning, the tables are dropped and are created again.
Derby and H2 don't support multiple transactions? I can't find anything that tells me the opposite.
My database configuration is:
<bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="persistenceUnitName" value="ORACLE_PU"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.DerbyPlatform"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="shared-cache-mode">NONE</prop>
<prop key="eclipselink.cache.shared.default">false</prop>
<prop key="eclipselink.query-results-cache">false</prop>
<prop key="eclipselink.weaving">false</prop>
<prop key="eclipselink.ddl-generation">${oracle.eclipselink.ddl.generation}</prop>
<prop key="eclipselink.ddl-generation.output-mode">database</prop>
<prop key="eclipselink.create-ddl-jdbc-file-name">create-tables.sql</prop>
<prop key="eclipselink.drop-ddl-jdbc-file-name">drop-tables.sql</prop>
<prop key="eclipselink.application-location">target/generated-sources/database</prop>
<prop key="eclipselink.jdbc.cache-statements">true</prop>
<prop key="eclipselink.custom.sql.import.file">${oracle.eclipselink.custom.sql.import.file}</prop>
...
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManager"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="url" value="jdbc:derby:target/memory;create=true"/>
<property name="username" value="test"/>
<property name="password" value="test"/>
</bean>
My attempt with H2 is similar but with the proper configurations. In weblogic environemnt everything works as expected.
What I'm missing?
It seems you are using derby in embedded in-memory mode. AFAIK, both derby and H2 support concurrent transactions only in standalone mode, when you connect through a TCP connection, but not in embedded mode. Try running derby as a seperate procese and change your database to connect to it.

how to control quartz scheduler from running using spring & weblogic deployment plan

i have a quartz scheduler configured with spring, it has five triggers
that trigger appropriate jobs. what i am looking for is to have flag
that i can use to disable the jobs in dev and test environments and
enable in production. below is configuration in my
applicationContext.xml for quartz Scheduler.
<!-- ====================================================================== -->
<!-- ========================== QUARTZ SCHEDULER ========================== -->
<!-- ====================================================================== -->
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="autoStartup" value="false" />
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="triggers">
<list>
<!-- if you remove a trigger, make sure you
also remove the trigger
from the QRTZ_TRIGGERS table.
-->
<ref bean="Trigger1" />
<ref bean="Trigger2" />
<ref bean="Trigger3" />
<ref bean="Trigger4"/>
<ref bean="Trigger5"/>
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">ClusteredScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">qrtz_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<!-- Set to 7 to correspond to the 7 nightly jobs that run in the morning -->
<prop key="org.quartz.threadPool.threadCount">7</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
</props>
</property>
</bean>
Cron Trigger :
<bean id="Trigger1" class="org.springframework.scheduling.quartz.CronTriggerBean" scope="prototype">
<property name="jobDetail">
<bean name="nightlyJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="My custom class that extends QuartzJobBean"/>
<property name="group" value="nightly"/>
<property name="requestsRecovery" value="true" />
</bean>
</property>
<!-- Cron expression to run job every 10 minutes for testing -->
<!-- <property name="cronExpression" value="0 0/10 * * * ?"/> -->
<!-- Cron expression that runs at 2:10AM -->
<property name="cronExpression" value="0 10 2 * * ?"/>
</bean>
What i tried : I tried setting the cron expression to feb31, so that
it will never run, but that requires a code change or a script to be
run in the database.
What i need : need a flag in my weblogic deployment plan that will turn on or off quartz scheduler
If you need to prevent all jobs from firing, cannot you just leave the scheduler in a stopped state on configured environments (i.e use autoStartup=false on dev/test and autoStartup=true on prod)? It is not actually clear to me how you start your scheduler on prod, because you already seem to have autoStart=false.
If the above is a no go, you have several options:
Separate (partial) Spring contexts with the schedulerBean for individual environments. Contexts for dev/test would contain empty job/trigger lists. Then you can use Spring profiles to pick the applicable context based on whatever condition you can think of (e.g. a domain suffix if you use .devel/.test/*.prod, some config value, JVM sys property etc.)
Implement SchedulerListener and make its schedulerStarted method pause the entire scheduler, or pause all job groups on dev/test.
Implement a TriggerListener and make its vetoJobExecution always return true for dev/test and false for prod.
BTW: If you want a visual tool to help you with pausing/unpausing schedulers, jobs and triggers etc., check out QuartzDesk. Disclaimer: I am the principal developer of this tool.

Intellij JPA Console with persistence.xml

I'm setting up a xml-free persistence JPA/Hibernate 4+/Spring 3+ using Intellij 13+. When I try to execute a query in the jpa console, I get the following error:
javax.persistence.PersistenceException: Unable to build entity manager factory
java.lang.RuntimeException: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.hibernate.dialect.PostgreSQL9Dialectt.PostgreSQL9Dialect] as strategy [org.hibernate.dialect.Dialect]
With the default postgres dialect, I get the same error.
Any idea what's going on?
Configuration extract:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.wikiz.service.model.rep" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="jadira.usertype.autoRegisterUserTypes">true</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
</bean>
And variables:
hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=create
Ok here it is.
I am not 100% sure if this helps your case but I think this is what you need to do:
Add a jdbc connection to your database from the database tab (usually to your right)
Then add the hibernate facet to your module
Go to modules (alt+ctrl+shift+s) then add it:
Now you have enabled the persistance tab on your left (usually) and you can assign a datasource to your
Now add the hibernate configuration but you have to add the xml file of hibernate. I haven't tried it with just adding the spring application context instead of hibernate.cfg.xml. Maybe it will work...
Now you have enable the presistance configuration for intellij and you can assign a datasource to it.
Select that datasource that you want and you will be able to use the JPA console with your jpa POJOs and HSQLs

Hibernate Session's get() function retrieves question marks instead of greek characters

I have a web application that uses spring and hibernate. My hibernate session factory is configured in spring as:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2005Dialect</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.example.dslibweb.model</value>
</list>
</property>
</bean>
The data source as:
<bean id="myDataSource" 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}" />
<property name="maxActive" value="${jdbc.maxConnections}" />
</bean>
and the properties file for the data source is:
jdbc.username=sa
jdbc.password=***
jdbc.url=jdbc:sqlserver://10.62.0.105:1433;databaseName=example;useUnicode=true;characterEncoding=utf-8
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.maxConnections=-1
I have a call:
DsActions action = (DsActions) this.hibernateCriteriaCommons.findById(id, new DsActions());
and findById is defined as:
public T findById(String id, Object model) {
return (T) this.sessionFactory.getCurrentSession().get(model.getClass(), id);
}
So I am calling the get method of hibernate session for a specific id and I expect an instance of type DsActions.
All works well when I run it from a local Tomcat instance (run through netbeans).
When I install it on a remote tomcat server, the instance of DsActions seems to have an encoding issue. When retriveing a field of DsActions instance I get question marks (??? ?????? ??????). The text is supposed to be greek characters
I am very confused, I do not understand why in the first case it is working and not in the second.
Note: the data is retrieved by the same database server, so no difference there. The only difference is the machine where the application is running.
Thank you all in advance.
I'm pretty sure that Hibernate retrieves that field correctly, and the problem is in the way you output these characters.
As a quick check you can add a condition such as f.contains("?") to your code and output its result - it should be false (if original string doesn't contain ?s, of course).
For possible problems in output see Unicode - How to get the characters right?.

Resources