Spring Batch: установка сущности внутри сущности - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть объект Пользователь , у которого есть другой объект в качестве Отдела.

@Entity
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer salary;

    @ManyToOne
    private Department department;
}

И другой отдел объекта

@Entity
@Getter
@Setter
public class Department {

    public Department(String departmentName){
        this.name = departmentName;
    }

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    private String name;
}

Процессор класс

@Component
public class Processor implements ItemProcessor<User, User> {

    @Override
    public User process(User item) throws Exception {
        return item;
    }
}

писатель класс

@Component
@Slf4j
public class DBWriter implements ItemWriter<User> {
    private final UserRepository userRepository;

    @Autowired
    public DBWriter(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void write(List<? extends User> users) throws Exception {
        log.info("Inserting value of user with data size: {}", users.size());
        userRepository.saveAll(users);
    }
}

И мой SpringBatchConfig класс

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {


    private final DepartmentRepository departmentRepository;

    public SpringBatchConfig(DepartmentRepository departmentRepository) {
        this.departmentRepository = departmentRepository;
    }

    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory,
                   StepBuilderFactory stepBuilderFactory,
                   ItemReader<User> reader,
                   ItemProcessor<User, User> process,
                   ItemWriter<User> writer
    ) {
        Step step = stepBuilderFactory.get("user-insertion")
                .<User, User>chunk(100000)
                .reader(reader)
                .processor(process)
                .writer(writer)
                .build();

        return jobBuilderFactory.get("user-insertion")
                .incrementer(new RunIdIncrementer())
                .start(step)
                .build();
    }

    @Bean
    public FlatFileItemReader<User> itemReader() {
        FlatFileItemReader<User> flatFileItemReader = new FlatFileItemReader<>();
        flatFileItemReader.setResource(new FileSystemResource("src/main/resources/users.csv"));
        flatFileItemReader.setName("CSV-Reader");
        flatFileItemReader.setLinesToSkip(1);
        flatFileItemReader.setLineMapper(getLineMapper());
        Department department = departmentRepository.save(new Department("Development"));
        return flatFileItemReader;
    }

    @Bean
    public LineMapper<User> getLineMapper() {
        DefaultLineMapper<User> defaultLineMapper = new DefaultLineMapper<>();

        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setDelimiter(",");
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames("name", "department", "salary");

        BeanWrapperFieldSetMapper<User> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(User.class);

        defaultLineMapper.setLineTokenizer(lineTokenizer);
        defaultLineMapper.setFieldSetMapper(fieldSetMapper);

        return defaultLineMapper;
    }
}

Я не могу назначить отдел пользователям во время пакетной вставки. Предположим, что текущий список пользователей может быть назначен одному отделу.

Как я могу вставить отдел в пользователя?

1 Ответ

0 голосов
/ 14 апреля 2020

Вы выполняете операцию записи в методе определения компонента считывателя:

Department department = departmentRepository.save(new Department("Development"));

Это не правильно. Не ожидается, что такой код будет написан в методе определения bean-компонента Spring.

Что вам нужно сделать, это заставить читателя прочитать User экземпляров и установить отдел для каждого экземпляра. Тогда ваш писатель спасет и пользователя, и его отдел. UserRepository должен уже сделать это, если ваше отображение JPA правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...