CHARAFI Saad
CHARAFI Saad

Reputation: 1440

how to indicate the end of csv file using spring batch?

I have a csv file that contains 4 lines. Step is executed normal, But it throws an error when it goes beyond the 4th line and I have only 4 lines.

in fieledSetMapper class I display the lines of my file

public class BatchFieldSetMapper implements FieldSetMapper<Batch>{

@Override
public Batch mapFieldSet(FieldSet fieldSet) throws BindException {

    Batch result = new Batch();

    result.setInstitution(fieldSet.readString(0));
    System.out.println("Institution ==> " + result.getInstitution());
    result.setType(fieldSet.readString(1));
    System.out.println("Type ==> " + result.getType());
    result.setNom(fieldSet.readString(2));
    System.out.println("Nom ==> " + result.getNom());
    result.setRubrique(fieldSet.readString(3));
    System.out.println("Rubrique ==> " + result.getRubrique());
    result.setMontantPaye(fieldSet.readDouble(4));
    System.out.println("MT P ==> " + result.getMontantPaye());
    result.setMontantRetenu(fieldSet.readDouble(5));    
    System.out.println("MT R ==> " + result.getMontantRetenu());

    return result;  

}

}

And this error appears

org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 5 in resource=[URL [file:C:/Temp/kk/xx.csv]], input=[;;;;;]

But I don't know how to indicate the end of the file normally it should do it automatically? no ?

PS : I upload the file using primefaces as UploadedFile And I convert it using this method to put it in a temporary file and for the batch to retrieve it and apply subsequent processing

    public void uploadFile(FileUploadEvent e) throws IOException{
    UploadedFile uploadedCsv=e.getFile();

    String filePath="C:/Temp/kk/xx.csv";
    byte[] bytes=null;

    if(uploadedCsv != null){
        bytes=uploadedCsv.getContents();
        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
        String filename = FilenameUtils.getName(uploadedCsv.getFileName());
        stream.write(bytes);
        stream.close();   
    }


    ApplicationContext context = new ClassPathXmlApplicationContext("spring-batch-context.xml");


    JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");


    Job job = (Job) context.getBean("batchJob");

    try {
        JobExecution execution = jobLauncher.run(job, new JobParameters());

    } catch (JobExecutionException e1) {
        System.out.println("Job Batch failed");
        e1.printStackTrace();
    }


}

And here is my spring-batch-context

    <!-- JobRepository and JobLauncher are configuration/setup classes -->
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />

<bean id="jobLauncher"  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
</bean>

<!-- à voir comment récuperer le nom du fichier et le mettre au value -->
<bean id="multiResourceItemReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
    <property name="resources" value="file:C:/Temp/kk/xx.csv" />
    <property name="delegate" ref="flatFileItemReader" />
</bean>

<!-- ItemReader reads a complete line one by one from input file -->
<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"  scope="step">

    <property name="lineMapper">

        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">

            <property name="fieldSetMapper">
                <!-- Mapper which maps each individual items in a record to properties in POJO -->
                <bean class="ma.controle.gestion.springbatch.BatchFieldSetMapper" />
            </property>

            <property name="lineTokenizer">
                <!-- A tokenizer class to be used when items in input record are separated by specific characters -->
                <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <property name="delimiter" value=";" />
                </bean>
            </property>

        </bean>

    </property>

</bean>


<!-- ItemWriter which writes data to database -->
<bean id="databaseItemWriter" class="org.springframework.batch.item.database.HibernateItemWriter">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>


<!-- Optional ItemProcessor to perform business logic/filtering on the input records -->
<bean id="itemProcessor" class="ma.controle.gestion.springbatch.BatchItemProcessor" />

<!-- Optional JobExecutionListener to perform business logic before and after the job -->
<bean id="jobListener" class="ma.controle.gestion.springbatch.BatchJobItemListener" />


<!-- Actual Job -->
<batch:job id="batchJob">
    <batch:step id="step1">
        <batch:tasklet transaction-manager="txManager">
            <batch:chunk reader="multiResourceItemReader" writer="databaseItemWriter"
                processor="itemProcessor" commit-interval="10" />
        </batch:tasklet>
    </batch:step>
    <batch:listeners>
        <batch:listener ref="jobListener" />
    </batch:listeners>
</batch:job>

Upvotes: 1

Views: 1846

Answers (1)

Srinivas K
Srinivas K

Reputation: 122

your 5th line is having empty values seems your BatchFieldSetMapper mapper is failing so your reader is throwing an exception.Can you check your mapper for null values.

Upvotes: 1

Related Questions