#kotlin #spring-batch #hypersql
Вопрос:
> Я хочу хранить данные во встроенной базе данных .Я принесу несколько предопределенных
данные и храните эти данные в базе данных. Я не знаю, какой это тип данных, поэтому я объявил каждый тип данных вещей как строку . когда я преобразую данные строки даты в локальную дату и пытаюсь сохранить их в базе данных, возникает эта ошибка
org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 1 in resource=[class path resource [result-match-metadata.csv]], input=[id city date player_of_match venue neutral_venue team1 team2 toss_winner toss_decision winner result result_margin eliminator method umpire1 umpire2]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:189) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:93) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:99) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:180) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:126) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:118) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:71) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:137) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.3.jar:4.3.3]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.3.jar:4.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.9.jar:5.3.9]
at jdk.proxy4/jdk.proxy4.$Proxy82.run(Unknown Source) ~[na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199) ~[spring-boot-autoconfigure-2.5.4.jar:2.5.4]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173) ~[spring-boot-autoconfigure-2.5.4.jar:2.5.4]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160) ~[spring-boot-autoconfigure-2.5.4.jar:2.5.4]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155) ~[spring-boot-autoconfigure-2.5.4.jar:2.5.4]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150) ~[spring-boot-autoconfigure-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:782) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:772) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:345) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.4.jar:2.5.4]
at com.nilmani.dashboardipl.DashboardIplApplicationKt.main(DashboardIplApplication.kt:13) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.5.4.jar:2.5.4]
Caused by: org.springframework.batch.item.file.transform.IncorrectTokenCountException: Incorrect number of tokens found in record: expected 17 actual 1
at org.springframework.batch.item.file.transform.AbstractLineTokenizer.tokenize(AbstractLineTokenizer.java:143) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:43) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:185) ~[spring-batch-infrastructure-4.3.3.jar:4.3.3]
... 56 common frames omitted
MatchInput.kt
package com.nilmani.dashboardipl.data
data class MatchInput(
val id: String? = null,
val city: String? = null,
val date: String? = null,
val player_of_match: String? = null,
val venue: String? = null,
val neutral_venue: String? = null,
val team1: String? = null,
val team2: String? = null,
val toss_winner: String? = null,
val toss_decision: String? = null,
val winner: String? = null,
val result: String? = null,
val result_margin: String? = null,
val eliminator: String? = null,
val method: String? = null,
val umpire1: String? = null,
val umpire2: String? = null,
)
matchitemprocessor.kt
package com.nilmani.dashboardipl.data
import com.nilmani.dashboardipl.entity.Match
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.batch.item.ItemProcessor
import java.time.LocalDate
class MatchInputItemProcessor : ItemProcessor<MatchInput,Match> {
val log:Logger = LoggerFactory.getLogger(MatchInputItemProcessor::class.java)
@Throws(Exception::class)
override fun process(item: MatchInput): Match? {
val match =Match()
match.id = java.lang.Long.valueOf(item.id)
match.city= item.city
match.date = LocalDate.parse(item.date)
match.playerOfMatch = item.player_of_match
match.venue = item.venue
/** set Team 1 and Team 2 depending on the innings*/
val firstIngTeam:String
val secondIngTeam:String
if ("bat" == item.toss_decision){
firstIngTeam = item.toss_winner.toString()
secondIngTeam =
if (item.toss_winner.equals(item.team1))item.team2.toString()
else
item.team1.toString()
}else{
secondIngTeam = item.toss_winner.toString()
firstIngTeam =
if (item.toss_winner.equals(item.team1))item.team2.toString()
else
item.team1.toString()
}
match.team1 = firstIngTeam
match.team2 = secondIngTeam
match.tossWinner = item.toss_winner
match.tossDecision = item.toss_decision
match.result = item.result
match.resultMargin = item.result_margin
match.umpire1= item.umpire1
match.umpire2 = item.umpire2
return match
}
}
batchconfig.kt
@Bean
fun reader(): FlatFileItemReader<MatchInput> {
return FlatFileItemReaderBuilder<MatchInput>()
.name("MatchItemReader")
.resource(ClassPathResource("match-data.csv"))
.delimited()
.names(*FIELD_NAMES)
.fieldSetMapper(object : BeanWrapperFieldSetMapper<MatchInput>() {
init {
setTargetType(MatchInput::class.java)
}
})
.build()
}
Match.kt
package com.nilmani.dashboardipl.entity
import java.time.LocalDate
import javax.persistence.Entity
import javax.persistence.Id
@Entity
data class Match(
@Id
var id: Long = 0,
var city: String? = null,
var date: LocalDate? = null,
var playerOfMatch: String? = null,
var venue: String? = null,
var team1: String? = null,
var team2: String? = null,
var tossWinner: String? = null,
var tossDecision: String? = null,
val matchWinner: String? = null,
var result: String? = null,
var resultMargin: String? = null,
var umpire1: String? = null,
var umpire2: String? = null
)
I want store csv data in to database
вот ИМЕНА ПОЛЕЙ
val FIELD_NAMES = arrayOf(
"id","city","date","player_of_match","venue","neutral_venue",
"team1","team2","toss_winner","toss_decision",
"winner","result","result_margin","eliminator","method","umpire1","umpire2"
)
batchconfig.kt
package com.nilmani.dashboardipl.data
import com.nilmani.dashboardipl.entity.Match
import org.springframework.batch.core.Job
import org.springframework.batch.core.Step
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.support.RunIdIncrementer
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider
import org.springframework.batch.item.database.JdbcBatchItemWriter
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder
import org.springframework.batch.item.file.FlatFileItemReader
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.io.ClassPathResource
import javax.sql.DataSource
@Configuration
@EnableBatchProcessing
class BatchConfig {
@Autowired
private lateinit var jobBuilderFactory: JobBuilderFactory
@Autowired
private lateinit var stepBuilderFactory: StepBuilderFactory
val FIELD_NAMES = arrayOf(
"id","city","date","player_of_match","venue","neutral_venue",
"team1","team2","toss_winner","toss_decision",
"winner","result","result_margin","eliminator","method","umpire1","umpire2"
)
@Bean
fun reader(): FlatFileItemReader<MatchInput> {
return FlatFileItemReaderBuilder<MatchInput>()
.name("MatchItemReader")
.resource(ClassPathResource("result-match-metadata.csv"))
.delimited()
.names(*FIELD_NAMES)
.fieldSetMapper(object : BeanWrapperFieldSetMapper<MatchInput>() {
init {
setTargetType(MatchInput::class.java)
}
})
.build()
}
}
Комментарии:
1. Можете ли вы показать фрагмент CSV-файла?
2. Я УЖЕ ДОБАВИЛ ЭТО, ПОЖАЛУЙСТА, ПРОВЕРЬТЕ ЭТО
3. Не могли бы вы, пожалуйста, показать, что
FIELD_NAMES
это такое? Кроме того, вы пробовали использовать более простой CSV-файл? Возможно, проблема не в коде, а в файле.4. Я предоставляю ИМЕНА ЧУВСТВ, которые вы можете проверить
5. Выглядит нормально. Вы пробовали использовать более простой CSV-файл? Возможно, проблема не в коде, а в файле.
Ответ №1:
Мне кажется, что вам не хватает конструктора без аргументов MatchInput
. Вы используете BeanWrapperFieldSetMapper
для сопоставления a FieldSet
с объектом. Если вы проверите справочную документацию для «setTargetType(тип)», вы найдете следующее:
Объект этого типа будет создаваться из конструктора по умолчанию для каждого вызова набора полей(FieldSet).
Попробуйте добавить конструктор без аргументов MatchInput
следующим образом:
data class MatchInput(
val id: String? = null,
val city: String? = null,
val date: String? = null,
val player_of_match: String? = null,
val venue: String? = null,
val neutral_venue: String? = null,
val team1: String? = null,
val team2: String? = null,
val toss_winner: String? = null,
val toss_decision: String? = null,
val winner: String? = null,
val result: String? = null,
val result_margin: String? = null,
val eliminator: String? = null,
val method: String? = null,
val umpire1: String? = null,
val umpire2: String? = null
) {
constructor() : this(null)
}