Organizing Spring Batch Jobs - spring

I would like to add a Spring Batch module to Java 1.8, Maven 3.3.3 project for running batch jobs.
The module(s) should be a Maven child
of this parent:
<parent>
<artifactId>portfolio-service-parent</artifactId>
<groupId>com.distributedfinance</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
At the moment I have three separate batch jobs. Is it better to organize all the batch jobs into one XML config file? Have three distinct modules each with it's own config file? One module with three distinct config files?
Thanks!
Here's the config file for the complex job:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/spring-util.xsd">
<bean name="jobParametersIncrementer" class="org.springframework.batch.core.launch.support.RunIdIncrementer"/>
<!-- BATCH-2351 workaround -->
<bean id="stepScope" class="org.springframework.batch.core.scope.StepScope">
<property name="autoProxy" value="true"/>
</bean>
<batch:job id="baiParseJob" incrementer="jobParametersIncrementer">
<batch:step id="baiParseStep" next="baiArchive">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="baiItemReader"
processor="baiItemProcessor"
writer="baiItemWriter"
commit-interval="1"/>
</batch:tasklet>
</batch:step>
<batch:step id="baiArchive">
<batch:tasklet ref="fileArchivingTasklet"/>
</batch:step>
</batch:job>
<bean id="baiItemReader" class="com.distributedfinance.mbi.bai.reader.MultiLineBaiItemReader"
scope="step">
<property name="delegate" ref="flatFileItemReader"/>
<property name="baiFileFieldSetMapper">
<bean class="com.distributedfinance.mbi.bai.mapper.BaiFileFieldSetMapper"/>
</property>
<property name="baiGroupFieldSetMapper">
<bean class="com.distributedfinance.mbi.bai.mapper.BaiGroupFieldSetMapper"/>
</property>
<property name="baiAccountFieldSetMapper">
<bean class="com.distributedfinance.mbi.bai.mapper.BaiAccountFieldSetMapper">
<property name="parser">
<bean class="com.distributedfinance.mbi.bai.mapper.BaiTypeParser"/>
</property>
</bean>
</property>
<property name="baiTransactionFieldSetMapper">
<bean class="com.distributedfinance.mbi.bai.mapper.BaiTransactionFieldSetMapper"/>
</property>
</bean>
<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" value="#{jobParameters['input.file.url']}"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"/>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper"/>
</property>
</bean>
</property>
</bean>
<bean id="baiItemProcessor" class="com.distributedfinance.mbi.bai.processor.BaiItemProcessor">
<constructor-arg index="0" ref="accountLookup"/>
<constructor-arg index="1">
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyMMddHHmmss"/>
</bean>
</constructor-arg>
</bean>
<bean id="baiItemWriter" class="com.distributedfinance.mbi.bai.writer.BaiItemWriter"/>
<bean id="accountLookup" class="com.distributedfinance.mbi.bai.lookup.AccountLookup"/>
<bean id="fileArchivingTasklet" class="com.distributedfinance.mbi.bai.tasklet.FileArchivingTasklet">
<property name="downloadFileKey" value="input.file.url"/>
<property name="archiveDirectory" value="${bai.sftp.archive-dir}"/>
<property name="purgeDays" value="${bai.sftp.purge-days}"/>
</bean>
</beans>

Related

Spring JMS 4.1 + ActiveMQ handle stress request

Currently, My system is using Spring-jms 4.1.6 and ActiveMQ 5.2.0
We facing the issue is that when we have stress requests (50000 continuity requests like DDOS), the server is dying.
I think there are some problems with my config on the consumer side;
The config below is the original config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
<!-- Administrated objects -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory" destroy-method="destroy">
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:(tcp://localhost:${JMS_PORT})"/>
</bean>
</property>
<property name="reconnectOnException" value="false"/>
</bean>
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="test.service" />
</bean>
<!-- Message listener container for services -->
<bean id="errorHandler" class="com.myconsumer.test.LogErrorHandler"/>
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queue" />
<property name="concurrentConsumers" value="10" />
<property name="maxConcurrentConsumers" value="20" />
<property name="messageListener" ref="serviceExporterDispatcher" />
<property name="errorHandler" ref="errorHandler" />
</bean>
<bean id="securityTokenVerificator" class="com.myconsumer.test.SecurityTokenVerificator">
<property name="authenticationService" ref="authenticationService" />
</bean>
<bean id="businessServiceInterceptor" class="com.myconsumer.test.RemoteInvocationBusinessServiceInterceptor">
<property name="securityTokenVerificator" ref="securityTokenVerificator" />
</bean>
<bean id="requestContextHandler" class="com.myconsumer.test.RequestContextHandler"/>
<bean id="remoteInvocationErrorHandler" class="com.myconsumer.test.RemoteInvocationErrorHandler" />
<bean id="serviceExporterDispatcher" class="com.myconsumer.test.ServiceExporterDispatcher">
<property name="businessServiceInterceptor" ref="businessServiceInterceptor" />
<property name="requestContextHandler" ref="requestContextHandler" />
<property name="remoteInvocationErrorHandler" ref="remoteInvocationErrorHandler" />
</bean>
</beans>
I tried with pool connection but it did not improve anything
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
<!-- Administrated objects -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:(tcp://localhost:${JMS_PORT})"/>
</bean>
</property>
<!-- <property name="reconnectOnException" value="false"/>
<property name="sessionCacheSize" value="3"/> -->
</bean>
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="test.service" />
</bean>
<!-- Message listener container for services -->
<bean id="errorHandler" class="com.myconsumer.test.LogErrorHandler"/>
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="destination" ref="queue" />
<property name="concurrentConsumers" value="10" />
<property name="maxConcurrentConsumers" value="20" />
<property name="messageListener" ref="serviceExporterDispatcher" />
<property name="errorHandler" ref="errorHandler" />
</bean>
<bean
class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="concurrency" value="3-10"/>
</bean>
<bean id="securityTokenVerificator" class="com.myconsumer.test.SecurityTokenVerificator">
<property name="authenticationService" ref="authenticationService" />
</bean>
<bean id="businessServiceInterceptor" class="com.myconsumer.test.RemoteInvocationBusinessServiceInterceptor">
<property name="securityTokenVerificator" ref="securityTokenVerificator" />
</bean>
<bean id="requestContextHandler" class="com.myconsumer.test.RequestContextHandler"/>
<bean id="remoteInvocationErrorHandler" class="com.myconsumer.test.RemoteInvocationErrorHandler" />
<bean id="serviceExporterDispatcher" class="com.myconsumer.test.ServiceExporterDispatcher">
<property name="businessServiceInterceptor" ref="businessServiceInterceptor" />
<property name="requestContextHandler" ref="requestContextHandler" />
<property name="remoteInvocationErrorHandler" ref="remoteInvocationErrorHandler" />
</bean>
</beans>
Update config for Producer
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Initialize service invoker properties -->
<bean id="propertyPlaceHolder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<bean factory-bean="resourceUtils" factory-method="getProperties">
<constructor-arg>
<bean factory-bean="resourceLoader"
factory-method="getResource">
<constructor-arg>
<value>service-invoker/service-invoker.properties</value>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<!-- Administrated objects -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory" destroy-method="destroy">
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${broker.url}"/>
</bean>
</property>
</bean>
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="${service.queue}" />
</bean>
<!-- Service Locator -->
<bean id="serviceLocator" class="com.myproducer.test.service.impl.ApplicationServiceLocatorImpl">
<property name="authenticationService" ref="authenticationService"/>
</bean>
<!-- Services -->
<bean id="authenticationService"
class="com.myproducer.test.service.impl.ClientJmsInvokerProxyFactoryBean">
<property name="serviceInterface" value="com.myservicer.test.authentication.v1.AuthenticationService" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="queue" ref="queue" />
<property name="receiveTimeout" value="${receiveTimeout}" />
</bean>
</beans>
Important
My 50000 request is sent frequently, I'm using nodejs to send and send the requests without waiting for the response to test the server.

How can I connect to two different databases, one for reading and one for writing in the same application using Spring?

Use Case: I am running a spring application which has orders. I can create plans for these orders. My dev environment/db does not have any orders and they come from a different application (we share the same db). So, Is there a way I can read orders from production database but when I create a plan, it gets saved to dev database?
My persistence.xml is as below
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="Demo_PU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.entity.ErrorMessage</class>
<class>com.entity.ErrorMessageTxt</class>
<class>com.entity.ErrorMessageTxtId</class>
<class>com.entity.Language</class>
<class>com.entity.TextEntity</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.InformixDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.id.new_generator_mappings" value="true" />
<property name="hibernate.cache.region.factory_class"
value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory" />
<property name="hibernate.cache.use_second_level_cache"
value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.generate_statistics" value="false" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding"
value="UTF-8" />
<!-- Adding timeouts for Lock Mode and Query -->
<property name="javax.persistence.query.timeout" value="60000" />
<property name="javax.persistence.lock.timeout" value="60000" />
</properties>
</persistence-unit>
</persistence>
My spring-config.xml is as below
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.project"/>
<context:component-scan base-package="com.project2"/>
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor"/>
<task:scheduler id="myScheduler"/>
<bean id="qa-informix" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dcSysCommon"/>
</bean>
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="dataSources">
<map>
<entry key="localDataSource" value-ref="qa-informix" />
</map>
</property>
<property name="defaultDataSource" ref="qa-informix"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum" />
<property name="jpaDialect">
<bean class="com.project.utils.IsolationSupportHibernateJpaDialect"/>
</property>
<property name="persistenceUnitName" value="PYD_PU" />
</bean>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- this enables the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<bean id="interpolator" class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator" ref="interpolator" />
</bean>
<bean class="com.project3.common.core.bo.LanguageBusinessObject" primary="true" />
<bean name="restUtils" class="com.project1.utils.RestUtils" />
<bean id="srvPropertyFile" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="srvPropertyFile" />
</bean>
<bean id="beanConfig" class="io.swagger.jaxrs.config.BeanConfig">
<property name="title" value="Swagger UI for QAS"/>
<property name="version" value="1.0.0" />
<property name="schemes" value="http" />
<property name="host" value="#{srvPropertyFile.hostName}:#{srvPropertyFile.pydPort}" />
<property name="basePath" value="planyourday/#{srvPropertyFile.countryCode}/#{srvPropertyFile.dcNumber}"/>
<property name="resourcePackage" value="com.project1.resources"/>
<property name="license" value="Apache 2.0 License"/>
<property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>
<property name="scan" value="true"/>
</bean>
<bean id="apiListingResource" class="com.project1.utils.SwaggerApiListingResource"/>
<bean id="swaggerSerializers" class="io.swagger.jaxrs.listing.SwaggerSerializers" scope="singleton"/>
</beans>
In my Jetty server config, I am defining the srvPropertyFile which references to the environment.properties file which has the database connection to dev db.
How should I manage my persistence context so that the entity manager used while reading orders and the entity manager used while creating plans connects to different databases?
you have to configure two persistence unit, data source and transaction manager(one for read and other for write) each.
While using entity manager specify the persistence unit like below.
PersistenceUnit(unitName = "x")
EntityManagerFactory entityManagerFactory;

JobRepositoryFactoryBean error spring batch

I started to learn spring batch and I have a problem that when i want to
persist the state of the job in a database using JobRepositoryFactoryBean.
compiler displays :
"Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobRepository' defined in class path resource [springConfig.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/core/simple/ParameterizedRowMapper"
but not error when i use MapJobRepositoryFactoryBean
I'm using spring 5
springconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:component-scan base-package="springbatch" />
<context:annotation-config />
<bean id="personneReaderCSV" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="input/personnes.txt" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="," />
<property name="names" value="id,nom,prenom,civilite" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="targetType" value="springbatch.entities.Personne" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<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/spring_test" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>springbatch.entities.Personne</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<job id="importPersonnes" xmlns="http://www.springframework.org/schema/batch">
<step id="readWritePersonne">
<tasklet>
<chunk reader="personneReaderCSV"
processor="personProcessor"
writer="personWriter"
commit-interval="2" />
</tasklet>
</step>
</job>
<bean id="daoPersonne" class="springbatch.dao.PersonneDaoImp">
<property name="factory" ref="sessionFactory"></property>
</bean>
<bean id="personWriter" class="springbatch.batch.PersonneWriter">
<property name="dao" ref="daoPersonne"></property>
</bean>
<bean id="personProcessor" class="springbatch.batch.PersonneProcess">
</bean>
<bean id="batchLauncher" class="springbatch.MyBean">
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="Mysql" />
</bean>
<task:scheduled-tasks>
<task:scheduled ref="batchLauncher" method="message"
cron=" 59 * * * * * " />
</task:scheduled-tasks>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="org/springframework/batch/core/schema-drop-mysql.sql" />
<jdbc:script location="org/springframework/batch/core/schema-mysql.sql" />
</jdbc:initialize-database>
</beans>
but not error when i use :
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
You are using Spring Batch v2.2 with Spring Framework 5. That's not going to work properly as ParameterizedRowMapper has been removed in Spring Framework 4.2+ (hence the exception).
I recommend that you use Spring Batch v4.1 (since v2.x is not maintained anymore) and your issue should be fixed.
The best way to manage Spring dependencies is to let Spring Boot do it for you either by generating a project from start.spring.io or by using the Spring Boot BOM. With both ways, you will have the correct Spring projects dependencies that are known to work well together.

Spring Batch taking too long

i am new spring batch. i recently tried a batch which will read records from file and insert into MariaDB. But for inserting 10k records its taking 2min 30sec.
I know its too much time. Table have only 3 columns without any Keys.
Here is my job-XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
">
<import resource="../../context.xml" />
<import resource="../../database.xml" />
<bean id="itemProcessor" class="com.my.sbatch.processors.CustomItemProcessor" />
<batch:job id="file_to_db">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager" start-limit="100">
<batch:chunk reader="cvsFileItemReader"
writer="databaseItemWriter" commit-interval="10">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="multiResourceReader"
class=" org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources"
value="file:batch/csv/processing/*.csv" />
<property name="delegate" ref="cvsFileItemReader" />
</bean>
<bean id="mappingBean" class="com.my.sbatch.bean.Batch1Bean"
scope="prototype" />
<bean name="customFieldSetMapper" class="com.my.sbatch.core.CustomFieldSetMapper">
<property name="classObj" ref="mappingBean"/>
</bean>
<bean id="cvsFileItemReader" class="com.my.sbatch.customReader.CustomItemReader" scope="step">
<property name="resource" value="file:#{jobParameters['inputFile']}" />
<property name="lineMapper">
<bean class="com.my.sbatch.core.CustomLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="#{jobParameters['delimiter']}" />
</bean>
</property>
<property name="fieldSetMapper" ref="customFieldSetMapper" />
</bean>
</property>
</bean>
<bean id="databaseItemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
#{jobParameters['insert_JobQuery']}
]]>
</value>
</property>
<property name="ItemPreparedStatementSetter">
<bean class="com.my.sbatch.core.CustomPreparedStatement" />
</property>
Here is my context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- stored job-meta in memory -->
<!--
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
-->
<!-- stored job-meta in database -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="mysql" />
</bean>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
In com.my.sbatch.core.CustomFieldSetMapper, com.my.sbatch.core.CustomPreparedStatement classes i am using reflections for mapping fields from File -> bean and Bean -> DB(Prepared statement).
Can you please advice me any solution for why it is taking too much time
In this example, your batch process is executed by a single thread. This may be the reason it takes so long. I recommend you use multhreading with TaskExecutor bean.
For example:
<batch:job id="file_to_db">
<batch:step id="step1">
<batch:tasklet task-executor="taskExecutor" transaction-manager="transactionManager" start-limit="100">
<batch:chunk reader="cvsFileItemReader"
writer="databaseItemWriter" commit-interval="10">
</batch:chunk>
</batch:tasklet>
</batch:step>
This is the simplest solution for multithreading but you may have problems in concurrent environments with access to information.
I recommend that you read this information to see the different scalability strategies.
More information about scalability here

java.lang.ClassCastException: org.apache.xerces.parsers.SAXParser cannot be cast to org.xml.sax.XMLReader Hibernate

I am working on a project with Hibernate JPA /spring.
It throws the following exception. After doing some reading I removed all the xml-apis from dependencies but it throws the same error. Any ideas ??
java.lang.ClassCastException: org.apache.xerces.parsers.SAXParser cannot be cast to org.xml.sax.XMLReader
at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:199)
at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:150)
at org.dom4j.io.SAXHelper.createXMLReader(SAXHelper.java:83)
at org.dom4j.io.SAXReader.createXMLReader(SAXReader.java:894)
at org.dom4j.io.SAXReader.getXMLReader(SAXReader.java:715)
at org.dom4j.io.SAXReader.setFeature(SAXReader.java:218)
at org.hibernate.internal.util.xml.MappingReader.setValidationFor(MappingReader.java:114)
at org.hibernate.internal.util.xml.MappingReader.readMappingDocument(MappingReader.java:77)
at org.hibernate.cfg.Configuration.add(Configuration.java:478)
at org.hibernate.cfg.Configuration.add(Configuration.java:474)
at org.hibernate.cfg.Configuration.add(Configuration.java:647)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:685)
at org.hibernate.ejb.Ejb3Configuration.addClassesToSessionFactory(Ejb3Configuration.java:1248)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1048)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:693)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
while I am trying to initialise the web context in jetty web server it throw the above exception.[Spring (3.0.6.Release) & hibernate (4.1.10.final) ]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<import resource="classpath*:/META-INF/spring-orchestra-init.xml"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="persistenceUnit">
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.faces.controller.jpa.JpaLoadTimeWeaver"/>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="conversation.access">
<bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="advices">
<list>
<ref bean="persistentContextConversationInterceptor" />
</list>
</property>
</bean>
</entry>
</map>
</property>
</bean>
<bean id="jpaPersistentContextFactory" class="org.apache.myfaces.orchestra.conversation.spring.JpaPersistenceContextFactory">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="persistentContextConversationInterceptor" class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
<property name="persistenceContextFactory" ref="jpaPersistentContextFactory" />
</bean>
<bean name="org.apache.myfaces.orchestra.conversation.AccessScopeManagerConfiguration"
class="org.apache.myfaces.orchestra.conversation.AccessScopeManagerConfiguration"
scope="singleton" lazy-init="true">
<property name="ignoreViewIds">
<set>
<value>/__ADFv__.xhtml</value>
</set>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#rum:1541:CHEZTST" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
After removing the loadtimeweaver property it worked fine.
<property name="loadTimeWeaver">
<bean class="org.faces.controller.jpa.JpaLoadTimeWeaver"/>
</property>
this is the link that shows that, although it is quite old it works
https://jira.springsource.org/browse/SPR-2596

Resources