4

I user spring-batch to locate entity by tables. Question is about ItemWriter or, may be, about ItemProcessor.

For this entity everything okey. I can read entity from source and save it table User_export

@Getter @Setter
class User{
    String objectId;
    String rev;
    String value;
    String type;
}

And I had this ItemWriter:

    @Bean
    @StepScope
    public ItemWriter<UserExport> writer() {
        JdbcBatchItemWriter<UserExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into User_export(objectId, REV, Value, Type)" +
                "values (:objectId, :rev, :value, :type)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

2) Than, I added field in my entity User. This field is list and I need to save this field in other table - Device_Export.

@Getter @Setter
class User{
    String objectId;
    String rev;
    String value;
    String type;
    List<String> devices;
}

I have two tables User_export and Device_export. Device_export has foreign key to User_export and relation is many devices to one user. I need to map my user-entity by tables. So, my solution is:

     @Bean
    public Step exportStep1() {
        return stepBuilderFactory.get("step1").<InputUser, List<OutputUser>>chunk(1)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }

reader->processor->writer

Reader (read entity from source talbe) - this is okey.

@Bean
public JdbcCursorItemReader<User> reader() {
    JdbcCursorItemReader<InputUser> reader = new JdbcCursorItemReader<>();
    String sql = "select * from User_Table";
    reader.setSql(sql);
    reader.setDataSource(dataSource);
    reader.setName("User_Table");
    reader.setRowMapper(new BeanPropertyRowMapper<>(User.class));
    return reader;
}

After processing, I have User entity with filled list of devices. I need to map it to tables:

I used ComposeWriter:

@Bean
    @StepScope
    @DependsOn({"userWriter", "deviceWriter"})
    public CompositeItemWriter composeWriter() {
        CompositeItemWriter writer = new CompositeItemWriter();

        ItemWriter<UserExport> userWriter = userWriter();
        ItemWriter<DeviceExport> deviceWriter = deviceWriter();
        List<ItemWriter> writers = new ArrayList<>();
        writers.add(userWriter);
        writers.add(deviceWriter);

        writer.setDelegates(writers);
        return writer;
    }


    @Bean
    @StepScope
    public ItemWriter<UserExport> userWriter() {
        JdbcBatchItemWriter<UserExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into User_Export (objectId, REV, Value, Type)" 
                "values (:objectId, :rev, :value, :type)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

    @Bean
    @StepScope
    public ItemWriter<DeviceExport> deviceWriter() {
        JdbcBatchItemWriter<DeviceExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into Device_Export (PR_KEY, objectId, device) values (:prKey, :objectId, :device)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

But with ItemWriter like this, I can just write only one record in devices table. How to write list of devices(records) in Device_export?

My approximately processor like this:

    @Bean
    public ItemProcessor<User, List<OutputUser>> processor() {
        return new ItemProcessor<User, List<OutputUser>>() {
            @Override
            public List<OutputUser> process(OutputUser item) throws Exception {
                OutputUser outputUser = mapToUser(item);
                List<OutputDevice> outputDevices = mapToDevices(item);
                // Не понятно что делать дальше
            }
        };
    }
2
  • How would you do it without Spring Batch? Commented Jul 11, 2019 at 12:51
  • @Mahmoud Ben Hassine I need do this with spring-batch only. Commented Jul 11, 2019 at 14:30

1 Answer 1

1

The JdbcBatchItemWriter won't help. You need to write the code to save a user with its devices and wrap that code is a custom Spring Batch writer. Otherwise use an ORM to map your entities to tables and use the JpaItemWriter or HibernateItemWriter.

A similar question here: Read one record/item and write multiple records/items using spring batch

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.