My spring batch application works fine with postgre version PostgreSQL 9.5.19 . I have to run this in a different environment with postgre version EnterpriseDB 9.5.0.5 . The following error comes. Is this a version problem? How to resolve this? Even though error says it is syntax problem, following select is working when it is executed in dbtool.
2023-07-13T03:06:51.166+05:30 WARN 32448 --- [cTaskExecutor-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42601
2023-07-13T03:06:51.167+05:30 ERROR 32448 --- [cTaskExecutor-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: syntax error at or near "$3"
Position: 549
2023-07-13T03:06:51.337+05:30 ERROR 32448 --- [cTaskExecutor-1] o.s.batch.core.step.AbstractStep : Encountered an error executing step swedbank.eod.file_gen.etl.to.file.step in job swedbank.eod.file_gen.job
org.springframework.dao.InvalidDataAccessResourceUsageException: JDBC exception executing SQL [select t1_0.trxn_no,t1_0.added_date,t1_0.auth_code,t1_0.base24_header,t1_0.crd_acpt_name_loc,t1_0.crd_no,t1_0.cashback_amt,t1_0.de63_1,t1_0.de63_19,t1_0.de63_ret,t1_0.de55,t1_0.exp_date,t1_0.frwd_inst_id,t1_0.merc_cat_code,t1_0.crd_acpt_id_code,t1_0.offline_flag,t1_0.particulars,t1_0.pos_cond_code,t1_0.pos_ent_mode,t1_0.proc_code,t1_0.retr_ref_no,t1_0.service_code,t1_0.term_id,t1_0.trxn_amt,t1_0.trxn_crtd_time,t1_0.trxn_curr_code,t1_0.trxn_typ from swt_dx_trxn_eod t1_0 where t1_0.added_date=? order by t1_0.trxn_no offset ? rows fetch first ? rows only] [ERROR: syntax error at or near "$3"
Position: 549] [n/a]; SQL [n/a]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:256) ~[spring-orm-6.0.9.jar:6.0.9]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:229) ~[spring-orm-6.0.9.jar:6.0.9]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550) ~[spring-orm-6.0.9.jar:6.0.9]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-6.0.9.jar:6.0.9]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-6.0.9.jar:6.0.9]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152) ~[spring-tx-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:134) ~[spring-data-jpa-3.1.0.jar:3.1.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.0.9.jar:6.0.9]
at jdk.proxy2/jdk.proxy2.$Proxy115.findByaddedDate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[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:568) ~[na:na]
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:283) ~[spring-core-6.0.9.jar:6.0.9]
at org.springframework.batch.item.data.RepositoryItemReader.doInvoke(RepositoryItemReader.java:265) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.item.data.RepositoryItemReader.doPageRead(RepositoryItemReader.java:228) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.item.data.RepositoryItemReader.doRead(RepositoryItemReader.java:174) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:95) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[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:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:702) ~[spring-aop-6.0.9.jar:6.0.9]
at org.springframework.batch.item.data.RepositoryItemReader$$SpringCGLIB$$0.read(<generated>) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:110) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:189) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:137) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:362) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:206) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:139) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:129) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:389) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:313) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-6.0.9.jar:6.0.9]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:256) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:362) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:206) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:139) ~[spring-batch-infrastructure-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:241) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:227) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:153) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:167) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:142) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:137) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:316) ~[spring-batch-core-5.0.2.jar:5.0.2]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:157) ~[spring-batch-core-5.0.2.jar:5.0.2]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.westpay.batch</groupId>
<artifactId>eod</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eod</name>
<description>Batch processing for eod file</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.2.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.9</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
属性文件
# Datasource
app.datasource.driverClassName=org.postgresql.Driver
app.datasource.ip=10.5.50.10
app.datasource.port=54765
app.datasource.name=db
app.datasource.username=user
app.datasource.url=jdbc:postgresql://${app.datasource.ip}:${app.datasource.port}/${app.datasource.name}
# JPA
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.generate_statistics=false
spring.batch.jdbc.initialize-schema=ALWAYS
与此问题相关的步骤类
@Component
@Slf4j
public class EnrichFileEodTableStepConfiguration extends AbstractStepProvider {
@Autowired
TransactionFileEodRepository transactionFileEodRepository;
@Bean
protected Step EnrichFileEodTable(TaskExecutor taskExecutor, JobRepository jobRepository,
PlatformTransactionManager transactionManager,
ItemReader<TransactionEod> transactionExtractRepositoryReader,
ItemProcessor<TransactionEod, TransactionFileEod> transactionTransformItemProcessor,
ItemWriter<TransactionFileEod> transactionLoadItemWriter){
return new StepBuilder(SwedBankEodFileGenerationJobProvider.NAMES_PREFIX + "etl.to.file.step", jobRepository)
.<TransactionEod, TransactionFileEod> chunk(GLOBAL_CHUNK_SIZE, transactionManager)
.reader(transactionExtractRepositoryReader)
.processor(transactionTransformItemProcessor)
.writer(transactionLoadItemWriter)
.allowStartIfComplete(true)
//.taskExecutor(taskExecutor)
.build();
}
@Bean
@StepScope
public RepositoryItemReader<TransactionEod> transactionExtractRepositoryReader
(TransactionEodRepository transactionEodRepository,
@Value("#{jobParameters[" + PARAM_CUTOFF_DATE_TIME + "]}") LocalDateTime cutoffDate){
try {
return new RepositoryItemReaderBuilder<TransactionEod>().name("ExtractTransactionReader")
.methodName("findByaddedDate")
.arguments(Arrays.asList(cutoffDate.toLocalDate()))
.sorts(Collections.singletonMap("trxnNo", Sort.Direction.ASC))
.repository(transactionEodRepository)
.pageSize(GLOBAL_CHUNK_SIZE)
.build();
}catch (Exception e) {
log.error(e.getMessage(), e);
throw e;
}
}
@Bean
@StepScope
public ItemProcessor<TransactionEod, TransactionFileEod> transactionTransformItemProcessor(){
return new EnrichFileEodItemProcessor();
}
@Bean
@StepScope
public RepositoryItemWriter<TransactionFileEod> transactionLoadItemWriter(){
try{
return new RepositoryItemWriterBuilder<TransactionFileEod>().methodName("save").repository(transactionFileEodRepository).build();
}catch (Exception e) {
log.error(e.getMessage(), e);
throw e;
}
}
}
批处理配置类
@Configuration
public class BatchConfiguration extends DefaultBatchConfiguration {
public static final int GLOBAL_CHUNK_SIZE = 100;
public static final String NETWORK_ID = "36";
@Value("${app.datasource.username}")
private String databaseUserName;
@Value("${app.datasource.driverClassName}")
private String driverClassName;
@Value("${app.datasource.url}")
private String dataSourceUrl;
@Autowired
DBPWDStoreClient client;
/**
*
* @return JobLauncher that is used to launch the batch job. this is overriden because to have an async job launcher
*/
@Bean
public JobLauncher jobLauncher() {
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
jobLauncher.setJobRepository(jobRepository());
jobLauncher.setTaskExecutor(taskExecutor());
try {
jobLauncher.afterPropertiesSet();
} catch (Exception e) {
throw new BatchConfigurationException("Unable to configure the default job launcher", e);
}
return jobLauncher;
}
/**
* @return async TaskExecutor
*/
@Bean
public TaskExecutor taskExecutor(){
SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
//asyncTaskExecutor.setConcurrencyLimit(2);
return asyncTaskExecutor;
}
/**
*
* @return PlatformTransactionManager
*/
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
@Bean
public DataSource dataSource(){
String sPassword = client.getPassword(databaseUserName);
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName(driverClassName);
dataSourceBuilder.url(dataSourceUrl);
dataSourceBuilder.username(databaseUserName);
dataSourceBuilder.password(sPassword);
return dataSourceBuilder.build();
}
}
存储库类
@Repository
public interface TransactionEodRepository extends JpaRepository<TransactionEod, Long> {
Page<TransactionEod> findAll(Pageable pageable);
@Modifying
@Query("DELETE TransactionEod t WHERE t.addedDate = :added_date")
int deleteEodTransactionsByAddedDate(@Param("added_date") LocalDate added_date);
@Query("from TransactionEod t WHERE t.addedDate = :addedDate")
Page<TransactionEod> findByaddedDate(@Param("addedDate") LocalDate addedDate, Pageable pageable);
}