【发布时间】:2019-10-22 22:48:47
【问题描述】:
我正在使用其中 db 表没有键的旧数据库。对于 java Sake,我必须使用 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);
}
}
错误日志
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}]]
注意:无论重复或任何其他问题,我都必须将所有数据插入表中,因为未定义键,因此每个数据都是有效的。
【问题讨论】:
-
你能改变目标表吗?
-
是的,我可以执行 DML 命令...
标签: spring-boot spring-data-jpa spring-data spring-batch