Showing posts with label SpringBatch. Show all posts
Showing posts with label SpringBatch. Show all posts

Spring Batch Hello World

Thursday, January 6, 2011

Spring batch is used to run the number of tasks parallelly

In this section, we will see Spring Batch in action by looking into an example. This example simply prints message in console

In Spring Batch, a Tasklet represents the unit of work to be done and in our example case, this would be printing a message.

Look at the following example


The following class implements Tasklet interface. this interface contains execute method. we have to override this method with our functionality.

In our example we are simply printing the passed message

HelloWorldTasklet.java

package com.raj.spring.batch.helloWorld;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

/**
 * @author nagarajuv
 *
 */

public class DynamicJobParameters implements JobParametersIncrementer {
public class HelloWorldTasklet implements Tasklet {

 private String printMessage;

 public void setPrintMessage(String printMessage) {
  this.printMessage = printMessage;
 }

 // @Override
 public RepeatStatus execute(StepContribution stepContribution,
   ChunkContext chunkContext) throws Exception {

  System.out.println("In Hello World Tasklet.!");
  System.out.println("Welcome to spring batch --"+printMessage);
  return RepeatStatus.FINISHED;
 }
}

in applicationContext.xml file we have to specify jobLauncher, datasource, jobRepository

for db configuration we have to run specific db scripts, you can get those from hereSpringBatchScripts
applicationContext.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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
    
    <!-- DATASOURCE, TRANSACTION MANAGER AND JDBC TEMPLATE -->
 <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/mydbtest" />
  <property name="username" value="raju" />
  <property name="password" value="raju" />
 </bean>
    
    <!-- JOB REPOSITORY - WE USE IN-MEMORY REPOSITORY FOR OUR EXAMPLE -->
 <bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
     <property name="dataSource" ref="dataSource"/>
       <property name="transactionManager" ref="transactionManager"/>
 </bean>
 
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource"/>
   </bean>
 
 <!-- With out DB connection -->
 <!-- 
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.SimpleJobRepository">
        <constructor-arg>
            <bean class="org.springframework.batch.core.repository.dao.MapJobInstanceDao"/>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.batch.core.repository.dao.MapJobExecutionDao" />
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.batch.core.repository.dao.MapStepExecutionDao"/>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.batch.core.repository.dao.MapExecutionContextDao"/>
        </constructor-arg>
    </bean>
         
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
    -->
</beans>

In helloworldJob.xml file we are importing applicationContext.xml file. and in this class we are declring jobs and tasklets. in our example job name is hellowWorldJob with two tasklets welcomeTasklet, printTasklet. we can write no of tasklets

In our web application, In particular class we can set jobParameters to the job in the following way

helloworldJob.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
         
  <import resource="applicationContext.xml"/>
    
  <bean id="welcomeTasklet" class="com.raj.spring.batch.helloWorld.HelloWorldTasklet">
   <property name="printMessage" value="Santosh"/>
  </bean>
  
  <bean id="printTasklet" class="com.raj.spring.batch.helloWorld.HelloWorldTasklet">
   <property name="printMessage" value="Nagaraju"/>
  </bean>
  
  <bean id="taskletStep" abstract="true"
   class="org.springframework.batch.core.step.tasklet.TaskletStep">
   <property name="jobRepository" ref="jobRepository"/>
  </bean>
  
  <bean id="helloWorldJob" class="org.springframework.batch.core.job.SimpleJob">
   <property name="restartable" value="true" />
   <property name="name" value="helloWorldJob" />
   <property name="steps">
    <list>
     <bean parent="taskletStep">
      <property name="tasklet" ref="welcomeTasklet"/>
      <property name="transactionManager" ref="transactionManager"/>
     </bean>
     <bean parent="taskletStep">
      <property name="tasklet" ref="printTasklet"/>
      <property name="transactionManager" ref="transactionManager"/>
     </bean>
    </list>
   </property>
   <property name="jobRepository" ref="jobRepository"/>
  </bean>
 </beans>
Through spring batch CommandLineJobRunner we can run this example by passing jobxml file name,jobname.
Main.java
package com.raj.spring.batch.helloWorld;

 import org.springframework.batch.core.launch.support.CommandLineJobRunner;

 /**
  * @author nagarajuv
  *
  */

 public class Main {
  public static void main(String[] args) {
   CommandLineJobRunner.main(new String[]{"helloWorldJob.xml", "helloWorldJob"});
  }
 }

If you want you can download this example at SpringBatchHelloWorld

Tags:Spring batch introduction, Sprig batch helloworld, DB-configuration in spring batch, commandline runner

Spring Batch DB configuration Sql Scripts

For Database configuration in spring batch we need to run the sql script.

The following are the sql scripts for different databases.

The sql scripts are availalble at spring-batch-core jar. we can simply extract the jar for these scripts

other wise you can simply download from the following location

Spring-Batch-All-Scripts

/* To empty the tables */
DELETE FROM BATCH_STEP_EXECUTION_CONTEXT;
DELETE FROM BATCH_JOB_EXECUTION_CONTEXT;
DELETE FROM BATCH_STEP_EXECUTION;
DELETE FROM BATCH_JOB_EXECUTION;
DELETE FROM BATCH_JOB_PARAMS;
DELETE FROM BATCH_JOB_INSTANCE;

/* To view the data in the tables */
select * from BATCH_JOB_INSTANCE;
select * from BATCH_JOB_PARAMS;
select * from BATCH_JOB_EXECUTION;
select * from BATCH_STEP_EXECUTION;
select * from BATCH_JOB_EXECUTION_CONTEXT;
select * from BATCH_STEP_EXECUTION_CONTEXT;

Tags:Spring batch job scripts for different databases. Spring batch Mysql scripts

A job instance already exists and is complete for parameters

Sunday, January 2, 2011

org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={}. If you want to run this job again, change the parameters.

Solution for the above exception is:

The meaning of the above exception is one instancce(instance name) is already exists in db
To avoid the above exception we have to follow the following process

The following class is used to set job parameters dynamically

DynamicJobParameters.java

package raj.spring.batch;

import java.util.Calendar;
import java.util.Date;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;

/**
 * @author nagarajuv
 *
 */

public class DynamicJobParameters implements JobParametersIncrementer {
 Date date = null;
 public JobParameters getNext(JobParameters parameters) {
  date = new Date();
    
  parameters = new JobParametersBuilder().addLong("currentTime", new Long(System.currentTimeMillis())).toJobParameters();
  
  return parameters;
 }
}

define the dynamicJobParameters bean .xml file

FileToTableJob.xml
<bean id="fileWritingJob" class="org.springframework.batch.core.job.SimpleJob" incrementer="dynamicJobParameters">

<bean id="dynamicJobParameters" class="com.ecomputercoach.DynamicJobParameters" />

Other wise we can follow other way alos

In our web application, In particular class we can set jobParameters to the job in the following way
Job job = null;
        JobParametersBuilder builder = null;
        JobParameters jobParameters = null;
        JobLauncher launcher = null;

        ApplicationContext context = AppContext.getApplicationContext();

        job = (Job) context.getBean("myjob");
        builder = new JobParametersBuilder();
        builder.addLong("currentTime", new Long(System.currentTimeMillis()));

        jobParameters = builder.toJobParameters();
        launcher = (JobLauncher) context.getBean("jobLauncher");
  launcher.run(job, jobParameters);


Tags:Spring batch job, dyamic parameters