Невозможно вставить строки в базу данных, используя данные Spring Batch + Spring - PullRequest
0 голосов
/ 07 июня 2019

Я работаю с устаревшей базой данных, в которой у таблиц БД нет ключей. Ради Java, я должен использовать Id аннотацию. Моя цель - прочитать данные из файла .dat и вставить их в таблицу. Я использую весеннюю партию для вышеуказанной цели. Для повышения производительности используется многопоточность. Но я получаю проблему вставки / обновления, которую я не могу понять. Я ссылался на многие источники, но, похоже, ни один не решает мою задачу. Пожалуйста, помогите мне, дав подходящее решение или ссылку. Заранее спасибо ...

Entity.java

@Entity
@Table(name = "int_repl_mkt_val")
public class IntReplMktVal implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private IntReplMktValId id;

    @Column(name = "acct_sys_cd")
    private String acctSysCd;

    @Column(name = "co_num", nullable = false)
    private Integer coNum;

    @Column(name = "last_mod_tmstmp")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModTmstmp;

    @Column(name = "pim_owned", nullable = false)
    private String pimOwned;

    @Column(name = "position", nullable = false)
    private BigDecimal position;

    @Column(name = "pricing_plan")
    private String pricingPlan;

    @Column(name="source_system",nullable=false)
    private String sourceSystem;

    ... getter and setter

}

EmbeddedClass.java

@Embeddable
public class IntReplMktValId implements Serializable 
{

    private static final long serialVersionUID = 4824041485763129937L;

    @Column(name = "acct_id",nullable=false)
    private Integer acctId;

    @Column(name = "asset_id",nullable=false)
    private Integer assetId;

    ... getter and setter
}

jpaRepository.class

@Repository
public interface IntReplMktValRepository extends JpaRepository<IntReplMktVal, IntReplMktValId> 
{

}

BatchConfiguration.class

@Configuration
public class IMAPPositionBatchConfiguration 
{
    @Autowired
    JobBuilderFactory jobBuilderFactory;

    @Autowired
    StepBuilderFactory stepBuilderFactory;

    @StepScope
    @Bean(name="imapPositionReader")
    public FlatFileItemReader<IMAPPositionInputMapperDTO> reader(@Value("#{jobParameters['fileName']}") String fileName) throws IOException 
    {
        FlatFileItemReader<IMAPPositionInputMapperDTO> newBean = new FlatFileItemReader<>();
        newBean.setName("fileReader");
        newBean.setResource(new InputStreamResource(FileUtils.openInputStream(new File(fileName))));
        newBean.setLineMapper(this.lineMapper());
        newBean.setLinesToSkip(1);
        return newBean;
    }

    public DefaultLineMapper<IMAPPositionInputMapperDTO> lineMapper() 
    {
        DefaultLineMapper<IMAPPositionInputMapperDTO> lineMapper = new DefaultLineMapper<>();
        lineMapper.setLineTokenizer(this.lineTokenizer());
        IMAPPositionReader imapPositionReader = new IMAPPositionReader();
        lineMapper.setFieldSetMapper(imapPositionReader);
        return lineMapper;
    }

    public DelimitedLineTokenizer lineTokenizer() 
    {
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setDelimiter("|");
        tokenizer.setNames("field1","field2","field3");
        tokenizer.setIncludedFields(5,4,7);
        return tokenizer;
    }

    public ItemProcessor<IMAPPositionInputMapperDTO, IntReplMktVal> processor() 
    {
        return new IMAPPositionProcessor();
    }

    @Bean(name="imapPositionBatchWriter")
    public ItemWriter<IntReplMktVal> writer() 
    {
        return new IMAPPositionWriter();
    }

    @Bean(name="imapPositionListener")
    public JobExecutionListenerSupport jobCompletionListener()
    {
        return new IMAPPositionJobListener();
    }

    @Bean(name="imapPositionTaskExecutor")    
    public ThreadPoolTaskExecutor taskExecutor() 
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);
        executor.setMaxPoolSize(100);
        return executor;
    }

    @Bean(name="imapPositionStep")
    public Step step(@Autowired @Qualifier("imapPositionTaskExecutor")TaskExecutor taskExecutor) throws IOException 
    {
        return stepBuilderFactory.get("imapPositionStep")
                .<IMAPPositionInputMapperDTO, IntReplMktVal>chunk(100)
                .reader(this.reader(null))
                .processor(this.processor())
                .writer(this.writer())
                .taskExecutor(taskExecutor)
                .build();
    }

    @Bean(name="imapPositionFileImportJob")
    public Job importUserJob(@Autowired @Qualifier("imapPositionStep") Step step) 
    {
        return jobBuilderFactory
                .get("imapPositionFileImportJob"+new Date())
                .incrementer(new RunIdIncrementer())
                .listener(this.jobCompletionListener())
                .flow(step)
                .end()
                .build();
    }

}

BatchWriter.java

public class IMAPPositionWriter implements ItemWriter<IntReplMktVal>
{
    @Autowired
    IntReplMktValRepository intReplMktValRepository;

    @Override
    public void write(List<? extends IntReplMktVal> items) throws Exception 
    {
        intReplMktValRepository.saveAll(items);     
    }

}

ErrorLog

2019-06-07 17:22:01,522 ERROR [scopedTarget.imapPositionTaskExecutor-4] org.hibernate.internal.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.HibernateException: Duplicate identifier in table for: [com.capgroup.horizon.pricecapture.entities.IntReplMktVal#component[acctId,assetId]{assetId=274800, acctId=1}]]

ПРИМЕЧАНИЕ. Я должен вставить все данные в таблицу независимо от дублирования или любой другой проблемы, поскольку ключи не определены, поэтому все данные действительны.

1 Ответ

0 голосов
/ 09 июня 2019

На самом деле проблема возникла из-за дублирования, обнаруженного в постоянном контексте, который был решен путем установки размера чанка равным 1.

...