I´m trying to get all fields from a table using spring batch.
I got all fields, except the ID fields (primary key e foreign key)
Below is my reader:
@Configuration
public class ReaderConfig {
@Bean
public JdbcCursorItemReader<Entity> Reader(
@Qualifier("datasource") DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<Entity>()
.name("Reader")
.dataSource(dataSource)
.sql("select * from table")
.rowMapper(new BeanPropertyRowMapper<Entity>(Entity.class))
.build();
}
}
Below is my writer:
@Configuration
public class WriterConfig {
@Bean
public ItemWriter<Entity> Writer() {
return entities-> entities.forEach(System.out::println);
}
}
The others fields comes with success, but the ID fields like transactionId and deposit comes null.
I think there is some kind of protection that not permit these fields show its values.
Someone can help me?
Advertisement
Answer
The column name in your table is ID_TRANSACTION
, but the getter/setter that you seem to be generating with lombok would be getTransactionId
/setTransactionId
, which do not match the column name. According to the javadoc of BeanPropertyRowMapper
, you can use an alias if the column name does not match the field name. Here is an excerpt from the javadoc:
To facilitate mapping between columns and fields that don't have matching names,
try using column aliases in the SQL statement like
"select fname as first_name from customer".
In your case, you need to update your query to something like:
select ID_TRANSACTION as transactionId, ID_DEPOSIT as depositId, /* other fields */ from rm_transaction
Here is a quick example:
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public JdbcCursorItemReader<Person> itemReader() {
String sql = "select person_id as id, name from person";
return new JdbcCursorItemReaderBuilder<Person>()
.name("personItemReader")
.dataSource(dataSource())
.sql(sql)
.beanRowMapper(Person.class) // equivalent to .rowMapper(new BeanPropertyRowMapper<>(Person.class))
.build();
}
@Bean
public ItemWriter<Person> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Person, Person>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfig.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Bean
public DataSource dataSource() {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JdbcTemplate jdbcTemplate = new JdbcTemplate(embeddedDatabase);
jdbcTemplate.execute("create table person (person_id int primary key, name varchar(20));");
for (int i = 1; i <= 10; i++) {
jdbcTemplate.execute(String.format("insert into person values (%s, 'foo%s');", i, i));
}
return embeddedDatabase;
}
static class Person {
private int id;
private String name;
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Person{id=" + id + ", name='" + name + ''' + '}';
}
}
}
This prints:
Person{id=1, name='foo1'}
Person{id=2, name='foo2'}
Person{id=3, name='foo3'}
Person{id=4, name='foo4'}
Person{id=5, name='foo5'}
Person{id=6, name='foo6'}
Person{id=7, name='foo7'}
Person{id=8, name='foo8'}
Person{id=9, name='foo9'}
Person{id=10, name='foo10'}
If you change the sql query to select * from person
, you will see the that the id field won’t be mapped correctly, because the BeanPropertyRowMapper
won’t find a getter/setter named getPerson_Id
/setPerson_Id
.