How to handle this use case in Spring Batch – Different Names?

Solution for How to handle this use case in Spring Batch – Different Names?
is Given Below:

There is a CSV file with many records where the CSV header names and the DB domain object names are different. How to fetch the CSV data and create a model to persist in the database in Spring Batch? Below throws errors since the header and db or jpa names are different

Example, employee.csv

Employee Id, Employee Name, Employee Address, Employee Address 2, Date Of Birth

Domain Object Employee.java

public string empId;   
public string empName;   
public string empAddress;   
public string empAddress2;   
public string empDOB;

Error thrown on the flat file reader

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;

@Component
@JobScope
public class EmployeeFlatFileItemReader extends FlatFileItemReader<Employee> implements StepExecutionListener {

private String fileName;
private String filePath;

@Override
public void beforeStep(StepExecution stepExecution) {
    fileName = (String) stepExecution.getJobExecution().getJobParameters().getString("fileName");  
    filePath = (String) stepExecution.getJobExecution().getJobParameters().getString("filePath");  
    setResource(new FileSystemResource(filePath));  
}

public EmployeeFlatFileItemReader() {
    try {
        //init();
        DefaultLineMapper<Employee> lineMapper = new DefaultLineMapper<Employee>() {
            {
                setLineTokenizer(new DelimitedLineTokenizer() {
                    {
                        setNames("Employee Id" + "," + "Employee Name" + "," + "Employee Address" + "," + "Employee Address 2" + "," + "Date Of Birth");
                    }
                });
                setFieldSetMapper(new BeanWrapperFieldSetMapper<Employee>() {
                    {
                        setTargetType(Employee.class); // Throws error
                    }
                });
            }
        };
        setLineMapper(lineMapper);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public ExitStatus afterStep(StepExecution stepExecution) {
    return stepExecution.getExitStatus();
}

}

You are passing a single String in the setNames method:

setNames("Employee Id" + "," + "Employee Name" + "," + "Employee Address" + "," + "Employee Address 2" + "," + "Date Of Birth");

This methods takes an array of Strings which correspond to field names in your domain type, not the header of the file (which should be skipped by the way using setLinesToSkip(1).

So you should update that line with something like:

setNames("empId" , "empName", "empAddress", "empAddress2", "empDOB");

Field names should be in the same order as they appear in the csv file.