I have a scenario where a given json file Employee.json needs to be read to Employee object and then written to employee table in mysql database in a batch process.
Employee.json:
[
{
"firstName": "John",
"lastName":"Snow",
"age":30
},
{
"firstName": "Tony",
"lastName": "Stark",
"age": 40
},
{
"firstName": "Peter",
"lastName":"Parker",
"age":35
}
]
Employee.java :
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Data
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private int age;
}
I used the JsonItemReader for reading the file from my resource location and RepositoryItemWriter for persisting the employee object.
This is how my batch config looks:
@Configuration
@ComponentScan(basePackages = "za.co.sanlam.employee")
@EnableBatchProcessing
@EnableTransactionManagement
public class DataInsertJsontoMysqlJob {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
PlatformTransactionManager platformTransactionManager;
@Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory;
@Value("input/Employee.json")
private Resource inputjson;
@Bean(name = "insertDataJob")
public Job job(@Qualifier("step1") Step step1) {
return jobBuilderFactory.get("insertDataJob").incrementer(new RunIdIncrementer()).start(step1).build();
}
@Bean
protected Step step1(ItemWriter writer) throws ParseException {
return stepBuilderFactory
.get("step1")
.transactionManager(platformTransactionManager)
.<Employee, Employee>chunk(2)
.reader(jsonItemReader())
.writer(writer)
.build();
}
@Bean
public JsonItemReader<Employee> jsonItemReader() {
return new JsonItemReaderBuilder<Employee>()
.jsonObjectReader(new JacksonJsonObjectReader<>(Employee.class))
.resource(inputjson)
.name("jsonItemReader")
.build();
}
@Bean
public RepositoryItemWriter<Employee> writer(EmployeeRepository repository) {
final RepositoryItemWriter<Employee> repositoryItemWriter = new RepositoryItemWriter<>();
repositoryItemWriter.setRepository(repository);
repositoryItemWriter.setMethodName("save");
return repositoryItemWriter;
}
}
Even though the item writer code is executed no data is getting persisted to the Employee table on my local mysql database. The application is able to connect to the database successfully and all the spring batch related tables are getting populated.
I was able to write the data to the Employee table if i use JdbcBatchItemWriter instead of RepositoryItemWriter:
@Bean //WORKING
public JdbcBatchItemWriter<Employee> writer(DataSource dataSource) {
JdbcBatchItemWriter<Employee> itemWriter = new JdbcBatchItemWriter<>();
itemWriter.setDataSource(dataSource);
itemWriter.setSql("insert into Employee (firstName,lastName,age) values (:firstName,:lastName,:age)");
itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
itemWriter.afterPropertiesSet();
return itemWriter;
}
I am not including my databaseconfiguration class here.
What am i missing while using RepositoryItemWriter ?
I guess EmployeeRepository
uses a JPA-based implementation. If this is the case, the cause of the issue would be that the platformTransactionManager
injected on your step is of type DataSourceTransactionManager
while it should be JpaTransactionManager
.
Make sure you are using a JpaTransactionManager
on your step and job repository when using RepositoryItemWriter
.