Invalid property 'durability' of bean class [org.springframework.scheduling.quartz.SchedulerFactoryBean] - quartz-scheduler

I am upgrading Spring from Spring 2.x to Spring 4.2.4 and Quartz from 1.8 to 2.3
Following bean throws "Invalid property 'durability' of bean class [org.springframework.scheduling.quartz.SchedulerFactoryBean]"
If I remove the durability property, I get "org.quartz.SchedulerException: Jobs added with no trigger must be durable"
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="durability" value="true"/>
<property name="recover" value="false"/>
<property name="jobDetails">
<list>
<ref bean="deleteTempFileJobScheduler" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="deleteTempFileJobSchedulerTrigger" />
</list>
</property>
</bean>
Any suggestion?
Thanks in advance.

A Quartz-Job has a attribute called durability.
This property determines whether a Job without triggers should automatically deleted.
I.e. if you set
<property name="durability" value="true"/>
than Jobs remain in the JobStore even if no triggers point to it anymore.
But if you set
<property name="durability" value="false"/>
than jobs should be removed from the JobStore if no triggers point to it.
In that case Quartz gives you the mentioned Exception if you try to add a Job without Triggers to the JobStore (since you add a Job which will be immediately removed).
To prevent such an Exception you could add a Job together with an Trigger to the JobStore.

You need set durability property to JobDetailFactoryBean
(in your case, this is deleteTempFileJobScheduler) and not to SchedulerFactoryBeam

When we are creating job itself , you can add storeDurably(true)
. It is work for me .
JobDetail job = newJob(JobScheduler.class)
.withIdentity( sc.getId()+ "_Job")
.usingJobData(getJobDataMap(sc))
.storeDurably(true)
.build();

Related

StrategySelectionException using HikariCP with hibernate

I am new to hibernate, and I have been tasked with changing the ConnectionProvider from the hibernate default CP to either Hikari (preferred) or C3P0 in a legacy Java application that does not use maven as a repository. The database is PostgreSQL. The hibernate version is hibernate-release-5.2.10.Final. I have added hibernate-hikaricp-5.2.10.Final.jar to the classpath.
I have a pre-existing xml configuration file for hibernate. This has been working for several years, but the project wants to change to a "production ready connection pool". I have added/modified properties for the connection provider as follows:
<property name="hibernate.connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</property>
<property name="hibernate.hikari.minimumIdle">5</property>
<property name="hibernate.hikari.maximumPoolSize">20</property>
<property name="hibernate.hikari.idleTimeout">30000</property>
I am getting the following StrategySelectionException (long stack trace reduced to exceptions/causes ... more information available if necessary).
Exception in thread "DatabaseCache initialize thread" org.hibernate.service.spi.ServiceException: Unable to
create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
...
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.hibernate.hikaricp.internal.HikariCPConnectionProvider] as strategy [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
I made one other change, after first seeing the exception. I added the following property, but it made no difference.
<property name="hibernate.implicit_naming_strategy">default</property>
The full configuration, with some information provided as variables replaced during build, is:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.implicit_naming_strategy">default</property>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</property>
<property name="hibernate.hikari.minimumIdle">5</property>
<property name="hibernate.hikari.maximumPoolSize">20</property>
<property name="hibernate.hikari.idleTimeout">30000</property>
<property name="hibernate.connection.username">${db_user_name}</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.url">${db_connection_url}</property>
<property name="hibernate.hbm2ddl.auto">none</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.jdbc.time_zone">GMT</property>
<property name="hibernate.generate_statistics">false</property> <!-- This affects performance, use only in development -->
<property name="show_sql">false</property>
</session-factory>
</hibernate-configuration>
Any strategies :D to address this would be welcome. Thanks.

No property called 'resource' in MultiResourceItemReader

In spring Batch doc (http://docs.spring.io/spring-batch/reference/html/scalability.html), under 7.4.3 section it is given that we can set the 'resource' property of MultiResourceItemReader from stepExecutionContext. But there is no property called 'resource' in MultiResourceItemReader, instead it is 'resources'.
Then how single resource can be set to MultiResourceItemReader from stepExecutionContext which will have single fileName in each context which was set during partitioning.
Instead it's called resources (which is an array) and it can be set like so:
<bean id="multiResourceReader"
class=" org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" value="file:some/folder/prefix*.csv" />
<property name="delegate" ref="flatFileItemReader" />
</bean>
When partitioning, you would not use a MultiResourceItemReader. Instead, just use a FlatFileItemReader in step scope.
<bean id="flatFileItemReader" scope="step"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="file:#{stepExecutionContext['FILE.NAME']}">
</bean>

propagation NOT_SUPPORTED creates failing transaction in JDBC when using ChainedTransactionManager (JDBC + JPA)

I'm working on an existing Spring application that uses JDBC (DAO's extend NamedParameterJdbcDaoSupport). There were four datasources configured, each with it's own DataSourceTransactionManager. (though only one was registered with tx:annotation-driven for some reason)
I've recently added JPA (Spring-data-JPA) into the application and configured two entityManagerFactories (for now I don't need the other two datasources). I also configured two JpaTransactionManagers and removed the corresponding DataSourceTransactionManagers for these dataSources, since the JpaTransactionManagers can also be used for JDBC transactions. (correct me if I'm wrong)
It appears I need to be able to have distributed transactions, since the two datasources (to two different databases) need to be accessed (through JPA) in one service method. Since I did not have all I need to set up JTA (missing XA-driver for one of the databases) I've decided to give the Spring ChainedTransactionManager a try. Sadly this didn't work out as expected. All works fine if I just call a service method that only uses JPA.
Though when I call an existing service method that uses a JDBC find that has a class level #transactional annotation with it's propagation set to NOT_SUPPORTED and call another service method after that with a JPA call and a #transactional, I get an exception:
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#462cf9d9] for key [org.jboss.jca.adapters.jdbc.WrapperDataSource#3fbb4c32] bound to thread [http-/127.0.0.1:8080-5]
at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:189) [spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:403) [spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
After some debugging, I found out that the transactions in Spring get added to a map on a ThreadLocal in the "TransactionSynchronizationManager.bindResource" method. The problem is that when using a JDBC call with #transactional and propogation NOT_SUPPORTED, a transaction is made anyway and registered through that method. When the JpaTransactionManager tries to bind it's resource, it is already on the map (and not marked as void) which causes the error to occur.
Changing the propagation to the default "REQUIRED" for the service call that encapsulates the JDBC call fixes the problem.
I have no idea why Spring is still creating that transaction when the transactional annotation is NOT_SUPPORTED. And if it creates that transaction, it should not bypass the JpaTransactionManager.
So what I'd like to know is if there is some way to tell Spring to use the JpaTransactionManager also when it creates a transaction itself inside the NamedParameterJdbcDaoSupport. (Well actually the JdbcDaoSupport... Well actually the DataSourceUtils)
We're using Spring 3.2.5, spring-data-jpa 1.6.0 and I've used Hibernate 4.2.0 as JpaVendor.
This problem doesn't occur without the ChainedTransactionManager.
Datasources:
<bean id="dataSourceCompta" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/comptaDS"/>
</bean>
<bean id="dataSourceUnisys" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/insoverDS"/>
</bean>
<bean id="dataSourceInsoverwebMysql" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/insoverWebDS"/>
</bean>
<bean id="dataSourceBatch" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/batchDS"/>
</bean>
Single remaining JDBC transaction manager (no JPA counterpart):
<bean id="transactionManagerBatch" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceBatch"/>
</bean>
JPA Transaction Managers:
<bean id="jpaUnisysTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryUnisys"/>
<qualifier value="unisys" />
</bean>
<bean id="jpaMysqlTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryMysql"/>
<qualifier value="mysql" />
</bean>
My ChainedTransactionManager:
<bean id="chainedTransactionManager" class="org.springframework.data.transaction.ChainedTransactionManager">
<constructor-arg>
<list>
<ref bean="jpaUnisysTransactionManager" />
<ref bean="jpaMysqlTransactionManager" />
</list>
</constructor-arg>
</bean>
JPA Entity manager factories:
<bean name="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
<bean id="entityManagerFactoryUnisys" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/some-persistence.xml"/>
<property name="dataSource" ref="dataSourceUnisys"/>
<property name="persistenceUnitName" value="unisysPU"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<!-- properties -->
</property>
</bean>
<bean id="entityManagerFactoryMysql" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/some-persistence.xml"/>
<property name="dataSource" ref="dataSourceCompta"/>
<property name="persistenceUnitName" value="mysqlPU"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<!-- properties -->
</property>
</bean>
For now I've "fixed" this, by changing all the class-level transactional annotations to have propagation.REQUIRED (default) instead of NOT_SUPPORTED. Though I do not really like this solutions, since it might be somebody set those propagations to NOT_SUPPORTED with a good reason. I've also tried SUPPORTED, but using that had the same issue as NOT_SUPPORTED: a transaction was being made anyway by the Spring DataSourceUtils when the query was being executed by the NamedParameterJdbcDaoSupport DAO.
When no transactional annotation is set on the service, all works well too.

apache restlet connector overload

I use restlet in camel route in from("restlet:http/myLink") clause. When user's requests more then ten per second, I begin recieve errors processing request like a "org.restlet.engine.connector.Controller run
INFO: Connector overload detected. Stop accepting new work"
I think, that error is caused by number of threads,request query's size or number,or something like that. I try set to maxThreads param different values in spring config
<bean id="restlet" class="org.apache.camel.component.restlet.RestletComponent">
<property name="maxThreads" value="15"/>
</bean>
but I am not succeed. In documentation http://camel.apache.org/restlet.html I ddin't find ant param for setting size\number of request queue. I need help :(
P.S. camel-restlet version is 2.12.2
Update
I try to set big numbers to maxThreads,maxConnectionsPerHost,maxTotalConnections, but it's useless. If inject org.restlet.Component to camel's config like that:
<bean id="restletComponent" class="org.restlet.Component" />
<bean id="restlet" class="org.apache.camel.component.restlet.RestletComponent">
<constructor-arg index="0">
<ref bean="restletComponent" />
</constructor-arg>
<property name="maxThreads" value="255"/>
<property name="maxConnectionsPerHost" value="1000"/>
<property name="maxTotalConnections" value="1000" />
</bean>
How I can override properties, that use BaseHelper params?
After go through the options of lowThread as well.
But I found current released camel doesn't support it.

Spring Integration 2 with Quartz scheduler

I am new to Spring Integration.
I've configured a Spring file inbound-channel-adapter, e.g.
<file:inbound-channel-adapter channel="channel1" directory="${location}" prevent-duplicates="true" filename-pattern="*.csv">
<si:poller>
<si:interval-trigger interval="1000"/>
</si:poller>
</file:inbound-channel-adapter>
<si:service-activator input-channel="channel1" output-channel="channel2" ref="filenameGenerator" method="generate"/>
Now this is working fine.
But this needs to be deployed in a clustered environment. I want to make sure that multiple instances in the cluster do not attempt to read the same file. So will this work in such environment?
If no, can I use Quartz scheduler like this:
<file:inbound-channel-adapter channel="channel1" directory="${location}" prevent-duplicates="true" filename-pattern="*.csv">
<si:poller task-executor="taskExecutor" fixed-rate="1000"/>
</file:inbound-channel-adapter>
<si:service-activator input-channel="channel1" output-channel="channel2" ref="filenameGenerator" method="generate"/>
<bean id="taskExecutor" class="org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor">
<property name="threadCount" value="20"/>
<property name="threadNamePrefix" value="consumer"/>
</bean>
Will this work and solve my problem??
Or do I have to use Transaction?
I hope the question is clear.
Thanks,
Adi
When multiple processes are reading from the same directory it can be
desirable to lock files to prevent them from being picked up
concurrently. To do this you can use a FileLocker
Check out the documentation around file lockers here. It seems that you can do soemthing like this:
<file:inbound-channel-adapter ... >
<file:nio-locker/>
</file:inbound-channel-adapter>
When multiple processes are reading from the same directory it can be
desirable to lock files to prevent them from being picked up
concurrently. To do this you can use a FileLocker
To ensure that a quartz-scheduled job executes once and only once within a cluster, configure a persistent, clustered quartz job schedule. Here's a sample config, for Quartz 1.6.6:
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- Set whether any jobs defined on this SchedulerFactoryBean should
overwrite existing job definitions.
-->
<property name="overwriteExistingJobs" value="true" />
<property name="dataSource" ref="myTransactionalDataSource" />
<!-- nonTransactionalDataSource is only necessary with clustered Quartz with an XA DataSource.
-->
<property name="nonTransactionalDataSource" ref="myNonTransactionalDataSource" />
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS WITH(UPDLOCK,HOLDLOCK) WHERE LOCK_NAME = ?</prop>
<!--
Run in cluster. Quartz ensures persisted jobs are executed once within the
cluster
-->
<prop key="org.quartz.jobStore.isClustered">true</prop>
<!-- Each node in the cluster must have a unique instance id.
-->
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<!-- Default clusterCheckinInterval is 15000
-->
<!-- <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
-->
</props>
</property>
<property name="transactionManager" ref="transactionManager" />
- <!--
In Quartz 1.6.6, Quartz's ThreadPool interface is used when firing job triggers,
in org.quartz.core.QuartzSchedulerThread.
Quartz 1.x still starts some unmanaged threads, notably org.quartz.impl.jdbcjobstore.JobStoreSupport's
ClusterManager which is used when clustered=true. Quartz 2.0 should correct this problem.
-->
<property name="taskExecutor" ref="myTaskExecutor" />
</bean>