org.springframework.batch.core.JobExecutionException: Partition handler returned an unsuccessful step in Spring Batch - spring

I am using Spring Batch using Spring Boot. In this example, I've implemented the Custom Partition since Employee Table has UUID value as a PK.
Error:
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30002ms.
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:307) ~[spring-jdbc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.sun.proxy.$Proxy74.getTransaction(Unknown Source) ~[na:na]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:137) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_171]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30002ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:689) ~[HikariCP-3.4.2.jar:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:196) ~[HikariCP-3.4.2.jar:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:161) ~[HikariCP-3.4.2.jar:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-3.4.2.jar:na]
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:263) ~[spring-jdbc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 25 common frames omitted
2020-05-16 20:55:22.675 INFO 31056 --- [cTaskExecutor-7] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--9] executed in 32s370ms
###################### 80
2020-05-16 20:55:22.787 INFO 31056 --- [TaskExecutor-10] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:70}] to localhost:27017
2020-05-16 20:55:22.815 INFO 31056 --- [TaskExecutor-10] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--8] executed in 32s510ms
###################### 50
###################### 70
2020-05-16 20:55:22.839 INFO 31056 --- [cTaskExecutor-1] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--5] executed in 32s539ms
###################### 20
###################### 40
2020-05-16 20:55:22.845 INFO 31056 --- [cTaskExecutor-4] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--7] executed in 32s540ms
###################### 10
2020-05-16 20:55:22.851 INFO 31056 --- [cTaskExecutor-9] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--2] executed in 32s546ms
###################### 30
2020-05-16 20:55:22.856 INFO 31056 --- [cTaskExecutor-3] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--1] executed in 32s556ms
###################### 100
###################### 60
2020-05-16 20:55:22.860 INFO 31056 --- [cTaskExecutor-6] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:71}] to localhost:27017
2020-05-16 20:55:22.864 INFO 31056 --- [cTaskExecutor-5] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--3] executed in 32s559ms
2020-05-16 20:55:22.867 INFO 31056 --- [cTaskExecutor-6] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--4] executed in 32s565ms
2020-05-16 20:55:22.874 INFO 31056 --- [cTaskExecutor-8] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--6] executed in 32s569ms
2020-05-16 20:55:22.883 INFO 31056 --- [cTaskExecutor-2] o.s.batch.core.step.AbstractStep : Step: [slaveStep:Thread--10] executed in 32s583ms
2020-05-16 20:55:22.885 ERROR 31056 --- [ main] o.s.batch.core.step.AbstractStep : Encountered an error executing step contactStepOne in job readContactJob
org.springframework.batch.core.JobExecutionException: Partition handler returned an unsuccessful step
at org.springframework.batch.core.partition.support.PartitionStep.doExecute(PartitionStep.java:112) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) [spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) [spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) [spring-batch-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) [spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.sun.proxy.$Proxy71.run(Unknown Source) [na:na]
at com.example.PostgresMongoContactsMigrationApplication.run(PostgresMongoContactsMigrationApplication.java:49) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at com.example.PostgresMongoContactsMigrationApplication.main(PostgresMongoContactsMigrationApplication.java:38) [classes/:na]
EmployeePartitions.java
public class EmployeePartitions implements Partitioner {
#Override
public Map<String, ExecutionContext> partition(int gridSize) {
Map<String, ExecutionContext> partitionMap = new HashMap<>();
int limit = 10;
int offset = 0;
int increment = 10;
int counter = 0;
for (int i = 0; i < 100; i += increment) {
counter++;
if (i == 0)
offset = i;
else
offset = i + 1;
limit = i + increment;
System.out.println("OFFSET " + offset + ", LIMIT = " + limit);
ExecutionContext context = new ExecutionContext();
context.put("limit", limit);
context.put("offset", offset);
partitionMap.put("Thread--" + counter, context);
System.out.println(partitionMap);
}
System.out.println(partitionMap.size());
return partitionMap;
}
}
EmployeeJob.java
#Configuration
public class EmployeeJob {
private static final Integer chunkSize = 200;
#Autowired
private DataSource dataSource;
#Autowired
private Environment env;
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Bean
public EmployeesPartitions EmployeesPartition() {
return new EmployeesPartitions();
}
#Bean("readEmployeeJob")
public Job readEmployeeJob() throws Exception {
return jobBuilderFactory.get("readEmployeeJob")
.incrementer(new RunIdIncrementer())
.start(EmployeeStepOne())
.build();
}
#Bean
public Step EmployeeStepOne() throws Exception {
return stepBuilderFactory.get("EmployeeStepOne")
.partitioner(slaveStep().getName(), EmployeesPartition())
.step(slaveStep())
.gridSize(1)
.taskExecutor(new SimpleAsyncTaskExecutor())
.build();
}
// slave step
#Bean
public Step slaveStep() throws Exception {
return stepBuilderFactory.get("slaveStep")
.<EmployeesDTO, EmployeesDTO>chunk(chunkSize)
.reader(EmployeeReader(null, null))
.writer(EmployeeWriter())
.build();
}
#Bean(destroyMethod = "")
#StepScope
public JdbcCursorItemReader<EmployeesDTO> EmployeeReader(
#Value("#{stepExecutionContext['limit']}") Long limit,
#Value("#{stepExecutionContext['offset']}") Long offset) throws Exception {
JdbcCursorItemReader<EmployeesDTO> reader = new JdbcCursorItemReader<>();
reader.setDataSource(this.dataSource);
reader.setSql("select * from scv_owner.Employees order by Employee_id limit "+ limit +" offset "+offset);
reader.setRowMapper(new EmployeeRowMapper());
reader.afterPropertiesSet();
return reader;
}
#Bean
public ItemProcessor<EmployeesDTO, EmployeesDTO> EmployeeProcessor() {
return new EmployeesProcessor();
}
#Bean
public ItemWriter<EmployeesDTO> EmployeeWriter() {
return new EmployeeWriter();
}
}

what would be the best size ?
There is no best size, it depends on the use case. For maximum throughput, you should set the pool size such as each partition can have its own connection if you want maximum throughput, otherwise choose the timeout depending on how long a partition would take to finish.
For example, if you have 10 partitions and a pool size of 5, 5 partitions will be working and 5 others will be waiting. Now if a partition takes at most 1 minute to finish, the timeout could be set to 1 minute (or probably a bit longer) such that waiting partitions are not timed out, aka a connection is returned to the pool before the timeout.

Related

Why are my connections not returning to the pool with Hikari?

We have this database layer with JdbcTemplate:
#Override
#Transactional
protected SomeObj insert(SomeObj obj) {
this.getNamedParameterJdbcTemplate().update(INSERT_QUERY, MyJdbcUtils.prepareQueryParams(obj));
synchronized (obj.getSomeList()) { decidable.getReasons().forEach(someItem -> { if (someItem != null) getJdbcTemplate().update(INSERT_ITEM_QUERY, obj.getId(), someItem ); }); }
return obj;
}
#Override
#Transactional
public SomeObj update(SomeObj obj) {
this.getNamedParameterJdbcTemplate().update(UPDATE_QUERY, MyJdbcUtils.prepareQueryParams(obj));
synchronized (obj.getSomeList()) { decidable.getReasons().forEach(someItem -> { if (someItem != null) getJdbcTemplate().update(UPDATE_ITEM_QUERY, obj.getId(), someItem ); }); }
return obj;
}
#Override
public SomeObj upsert(SomeObj obj) {
try {
return this.insert(obj);
} catch (DuplicateKeyException exception) {
final SomeObj existingObj = this.find(obj.getSomeId()).get(0);
// Populate some fields from existing object
}
return this.update(transaction);
}
MyJdbcUtils is as follows:
public static Map<String, ?> prepareQueryParams(SomeObj obj) {
return new HashMap<String, Object>() {{
put("someColumn", obj.getSomeColumn());
...
}};
}
My database related application.properties are as follows:
spring.datasource.jdbc-url=...
spring.datasource.username=...
spring.datasource.password=...
spring.datasource.initialization-mode=never
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.leakDetectionThreshold=5000
spring.datasource.maximumPoolSize=100
spring.datasource.minimumIdle=20
spring.datasource.idleTimeout=30000
After a while, Hikari pool logs looks like this:
HikariPool-1 - Timeout failure stats (total=100, active=100, idle=0, waiting=2)
with a lot of:
Connection leak detection triggered for org.postgresql.jdbc.PgConnection#17b19afa on thread http-nio-8080-exec-100, stack trace follows
java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-3.4.1.jar!/:?]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:104) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:134) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:250) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:258) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:246) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:83) ~[hibernate-core-5.4.6.Final.jar!/:5.4.6.Final]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:184) ~[spring-orm-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:402) ~[spring-orm-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at com.company.project.core.domain.transaction.JdbcTransactionDaoImpl$$EnhancerBySpringCGLIB$$87fab16e.update(<generated>) ~[classes!/:?]
at com.company.project.core.integration.spring.TransactionIntegrationConfiguration.asyncPersistenceService(TransactionIntegrationConfiguration.java:208) ~[classes!/:?]
at sun.reflect.GeneratedMethodAccessor326.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) ~[spring-messaging-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) ~[spring-messaging-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:508) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:478) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean$Invoker.get(GatewayProxyFactoryBean.java:1012) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_212]
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) ~[?:1.8.0_212]
at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.submit(ThreadPoolTaskExecutor.java:341) ~[spring-context-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:451) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at com.sun.proxy.$Proxy181.processTransaction(Unknown Source) ~[?:?]
at com.company.project.core.services.transaction.TransactionServiceImpl.async(TransactionServiceImpl.java:101) ~[classes!/:?]
at com.company.project.core.services.transaction.TransactionServiceImpl$$FastClassBySpringCGLIB$$73b9cf27.invoke(<generated>) ~[classes!/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at com.company.project.core.services.transaction.TransactionServiceImpl$$EnhancerBySpringCGLIB$$eae305f2.async(<generated>) ~[classes!/:?]
at com.company.project.core.controllers.TransactionController.async(TransactionController.java:52) ~[classes!/:?]
at sun.reflect.GeneratedMethodAccessor323.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
until:
HikariPool-1 - Connection is not available, request timed out after 30000ms
DBA confirms that the longest query is ~1second and I'm sure that the queries should run around that long. What am I doing wrong? Why aren't my connections returning to the pool and are still marked as active?
Update:
As per comments, I switched the logic to:
private final TransactionTemplate transactionTemplate;
#Autowired
public MyDao (PlatformTransactionManager transactionManager, DataSource dataSource) {
setDataSource(dataSource); // Class extends NamedParameterJdbcDaoSupport
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
#Override
protected SomeObj insert(SomeObj obj) {
return this.transactionTemplate.execute(status -> {
this.getNamedParameterJdbcTemplate().update(INSERT_QUERY, MyJdbcUtils.prepareQueryParams(obj));
for (String someItem : obj.getSomeList()) if (someItem != null) getJdbcTemplate().update(INSERT_ITEM_QUERY, obj.getId(), someItem );
return obj;
});
}
#Override
public SomeObj update(SomeObj obj) {
return this.transactionTemplate.execute(status -> {
this.getNamedParameterJdbcTemplate().update(UPDATE_QUERY, MyJdbcUtils.prepareQueryParams(obj));
for (String someItem : obj.getSomeList()) if (someItem != null) getJdbcTemplate().update(UPDATE_ITEM_QUERY, obj.getId(), someItem );
return obj;
});
}
However the issue did not resolve.

StoredProcedureItemReader not able to retry on java.sql.SQLTimeoutException

I am having difficulty in getting my StoredProcedureItemReader to Retry after it fails due to SQLTimeoutException.
Here is the configuration for my step process:
#Bean
public Step Step() throws Exception {
return stepBuilderFactory.get("Step")
.<Student, Student>chunk(100)
.reader(storedProcItemReader())
.processor(studentItemProcessor)
.writer(fileItemWriter())
.faultTolerant()
.retryLimit(5)
.retry(QueryTimeoutException.class)
.retry(SQLTimeoutException.class)
.backOffPolicy(backoffPolicy())
.build();
}
#Bean
#StepScope
public RetryableItemReader<Student> storedProcItemReader() throws Exception {
return studentItemReader.getDataFromDatabase(dataSource);
}
studentItemReader class file:
#Component
#StepScope
public class studentItemReader{
public RetryableItemReader<Student> getDataFromDatabase(DataSource dataSource) {
RetryTemplate retryTemplate = RetryTemplate.builder()
.maxAttempts(5)
.exponentialBackoff(1000, 2, 20000)
.retryOn(QueryTimeoutException.class)
.retryOn(SQLTimeoutException.class)
.build();
StoredProcedureItemReader<RegionResponse> reader = new StoredProcedureItemReader<>();
SqlParameter[] parameter = { new SqlParameter("#studentId",
java.sql.Types.INTEGER) };
PreparedStatementSetter statementValues = new PreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setInt(1, parameterValue);
}
};
reader.setDataSource(dataSource);
reader.setProcedureName("dbo.StudentReport");
reader.setParameters(parameter);
reader.setPreparedStatementSetter(statementValues);
reader.setRowMapper(new StudentRowMapper());
reader.setQueryTimeout(1500);
return new RetryableItemReader<>(reader, retryTemplate);
}
}
}
Retry:
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamReader;
import org.springframework.batch.item.database.StoredProcedureItemReader;
import org.springframework.retry.support.RetryTemplate;
public class RetryableItemReader<T> implements ItemStreamReader<T> {
private final StoredProcedureItemReader<T> delegate;
private final RetryTemplate retryTemplate;
public RetryableItemReader(StoredProcedureItemReader<T> delegate, RetryTemplate retryTemplate) {
this.delegate = delegate;
this.retryTemplate = retryTemplate;
}
#Override
public T read() throws Exception {
return retryTemplate.execute(context -> delegate.read());
}
#Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
delegate.open(executionContext);
}
#Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
delegate.update(executionContext);
}
#Override
public void close() throws ItemStreamException {
delegate.close();
}
}
I am seeing this in the logs where it isn't able to retry:
2021-09-09 19:21:10.405 [SimpleAsyncTaskExecutor-4] WARN c.z.hikari.pool.ProxyConnection:182 - HikariPool-1 - Connection ConnectionID:4 ClientConnectionId: bf81d056-0bc4-4657-b201-bc638d128f13 marked as broken because of SQLSTATE(HY008), ErrorCode(0)
java.sql.SQLTimeoutException: The query has timed out.
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:505)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:213)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$FastClassBySpringCGLIB$$7ad4b84a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$EnhancerBySpringCGLIB$$a742dbe0.open(<generated>)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:114)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
2021-09-09 19:21:10.406 [SimpleAsyncTaskExecutor-3] DEBUG o.s.retry.support.RetryTemplate:324 - Retry: count=0
2021-09-09 19:21:10.406 [SimpleAsyncTaskExecutor-3] DEBUG o.s.retry.support.RetryTemplate:324 - Retry: count=0
2021-09-09 19:21:10.408 [SimpleAsyncTaskExecutor-3] DEBUG o.s.retry.support.RetryTemplate:324 - Retry: count=0
2021-09-09 19:21:10.522 [SimpleAsyncTaskExecutor-1] ERROR o.s.batch.core.step.AbstractStep:237 - Encountered an error executing step slaveStep in job Pit-Extract
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:153)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$FastClassBySpringCGLIB$$7ad4b84a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$EnhancerBySpringCGLIB$$a742dbe0.open(<generated>)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:114)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.dao.QueryTimeoutException: Executing stored procedure; SQL [{call dbo.StudentReport(?)}]; The query has timed out.; nested exception is java.sql.SQLTimeoutException: The query has timed out.
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:76)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:229)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150)
... 21 common frames omitted
Caused by: java.sql.SQLTimeoutException: The query has timed out.
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:505)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:213)
... 23 common frames omitted
2021-09-09 19:21:10.522 [SimpleAsyncTaskExecutor-4] ERROR o.s.batch.core.step.AbstractStep:237 - Encountered an error executing step slaveStep in job Pit-Extract
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:153)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$FastClassBySpringCGLIB$$7ad4b84a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$EnhancerBySpringCGLIB$$a742dbe0.open(<generated>)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:114)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.dao.QueryTimeoutException: Executing stored procedure; SQL [{call dbo.StudentReport(?)}]; The query has timed out.; nested exception is java.sql.SQLTimeoutException: The query has timed out.
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:76)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:229)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150)
... 21 common frames omitted
Caused by: java.sql.SQLTimeoutException: The query has timed out.
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:505)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:213)
... 23 common frames omitted
2021-09-09 19:21:10.582 [SimpleAsyncTaskExecutor-2] WARN c.z.hikari.pool.ProxyConnection:182 - HikariPool-1 - Connection ConnectionID:5 ClientConnectionId: 161fd25b-5a39-465c-b1a6-8116952b1972 marked as broken because of SQLSTATE(HY008), ErrorCode(0)
java.sql.SQLTimeoutException: The query has timed out.
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:505)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:213)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$FastClassBySpringCGLIB$$7ad4b84a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$EnhancerBySpringCGLIB$$a742dbe0.open(<generated>)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:114)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
2021-09-09 19:21:10.583 [SimpleAsyncTaskExecutor-2] ERROR o.s.batch.core.step.AbstractStep:237 - Encountered an error executing step slaveStep in job Pit-Extract
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:153)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$FastClassBySpringCGLIB$$7ad4b84a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader$$EnhancerBySpringCGLIB$$a742dbe0.open(<generated>)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:114)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:138)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:135)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.dao.QueryTimeoutException: Executing stored procedure; SQL [{call dbo.StudentReport(?)}]; The query has timed out.; nested exception is java.sql.SQLTimeoutException: The query has timed out.
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:76)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:229)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150)
... 21 common frames omitted
Caused by: java.sql.SQLTimeoutException: The query has timed out.
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:505)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)
at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:213)
... 23 common frames omitted
2021-09-09 19:21:12.888 [custom-executor1] ERROR o.s.batch.core.step.AbstractStep:237 - Encountered an error executing step masterStep in job Student-Info-Extract
org.springframework.batch.core.JobExecutionException: Partition handler returned an unsuccessful step
at org.springframework.batch.core.partition.support.PartitionStep.doExecute(PartitionStep.java:112)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:137)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Please let me what mistake I am doing here. Thanks in advance!
Your RetryableItemReader only retries the read operation, but the timeout is happening while initializing the reader, ie in the open method. This can be seen here:
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:153)
at gov.va.med.ccrs.pit.extract.retry.RetryableItemReader.open(RetryableItemReader.java:25)
...
This method is not retried in your RetryableItemReader. You can make it retryable as you did for the read method, something like:
#Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
retryTemplate.execute(new RetryCallback<Object, ItemStreamException>() {
#Override
public Object doWithRetry(RetryContext retryContext) throws ItemStreamException {
delegate.open(executionContext);
return null;
};
});
}
That said, I would investigate why the timeout is happening as it could happen again down the road when reading actual data (even if this is retried).

Spring boot LDAP get memberOf in ODM

I'm currenly building an application using Spring boot LDAP, but have some problems accessing the 'memberOf' property to determine which groups the users belongs to.
I have seen Spring LDAP and MemberOf but I am using the ODM to get the user from LDAP, when trying to add the 'memberOf' property I get the following error:
org.springframework.ldap.odm.core.impl.MetaDataException: Can't determine destination type for field private java.util.ArrayList nl.quintor.afstudeermanagementtool.entitiy.LdapUser.memberOf in class class nl.quintor.afstudeermanagementtool.entitiy.LdapUser
at org.springframework.ldap.odm.core.impl.AttributeMetaData.determineFieldType(AttributeMetaData.java:167) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.odm.core.impl.AttributeMetaData.<init>(AttributeMetaData.java:234) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.odm.core.impl.ObjectMetaData.<init>(ObjectMetaData.java:132) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper.addManagedClass(DefaultObjectDirectoryMapper.java:151) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper.getEntityData(DefaultObjectDirectoryMapper.java:108) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper.filterFor(DefaultObjectDirectoryMapper.java:468) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1824) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.core.LdapTemplate.findAll(LdapTemplate.java:1806) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.ldap.core.LdapTemplate.findAll(LdapTemplate.java:1814) ~[spring-ldap-core-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.ldap.repository.support.SimpleLdapRepository.findAll(SimpleLdapRepository.java:183) ~[spring-data-ldap-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[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:566) ~[na:na]
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:550) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at com.sun.proxy.$Proxy82.findAll(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:62) ~[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:566) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at com.sun.proxy.$Proxy82.findAll(Unknown Source) ~[na:na]
at nl.quintor.afstudeermanagementtool.seeders.DatabaseSeeder.seedUserTable(DatabaseSeeder.java:59) ~[classes/:na]
at nl.quintor.afstudeermanagementtool.seeders.DatabaseSeeder.seed(DatabaseSeeder.java:39) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[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:566) ~[na:na]
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:305) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:190) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:153) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.14.RELEASE.jar:5.2.14.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236) ~[spring-boot-2.3.10.RELEASE.jar:2.3.10.RELEASE]
at nl.quintor.afstudeermanagementtool.AfstudeermanagementtoolApplication.main(AfstudeermanagementtoolApplication.java:16) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[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:566) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.10.RELEASE.jar:2.3.10.RELEASE]
2021-05-18 16:14:16.109 INFO 14468 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-05-18 16:14:16.112 INFO 14468 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2021-05-18 16:14:16.139 INFO 14468 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Process finished with exit code 0
The code I'm using is:
#Entry(
objectClasses = { "user, Person", "top", "organizationalPerson" })
public class LdapUser {
private #Id Name id;
private #Attribute(name = "cn") String fullName;
private #Attribute(name = "sAMAccountName") String username;
private #Attribute(name ="memberof", readonly = true)
ArrayList<?> memberOf;
public LdapUser() { }
public LdapUser(String fullName, String username, ArrayList<?> memberOf) {
this.fullName = fullName;
this.username = username;
this.memberOf = memberOf;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public ArrayList<?> getMemberOf() {
return memberOf;
}
public void setMemberOf(ArrayList<?> memberOf) {
this.memberOf = memberOf;
}
}
This appears to be a "shortcoming" common to reflection-based object mapping frameworks in Java.
Annotating Java class fields with #Attribute only works if the annotated field is a concrete type: that is why the annotation works with ArrayList<String> but not List<String> or ArrayList<?>, because in the latter two cases the object mapper would have to 'guess' which concrete type to use when populating that field. In other words, the object mapper cannot call new List<String>(), so it throws an exception.
You can read about a similar problem affecting the JPA ORM standard. JPA appears to have a workaround by providing the targetEntity attribute element, but this is only present on some of their annotations (like #ManyToMany), and not on #Column, which is roughly equivalent to #Attribute here.

How to use alias in JPQL?

I am working on Spring Boot v2.2.2.RELEASE and Spring Data JPA. I want to convert below SQL into JPQL
SELECT
YEAR(orderDate) AS year,
SUM(quantityOrdered * priceEach) AS total
FROM
orders
INNER JOIN orderdetails
USING (orderNumber)
WHERE
status = 'Shipped'
GROUP BY
year
HAVING
year > 2003;
Error
2019-12-27 11:23:43.077 WARN 1536 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22
2019-12-27 11:23:43.077 ERROR 1536 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'order0_.orderDate' in 'having clause'
2019-12-27 11:23:43.084 INFO 1536 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-12-27 11:23:43.094 ERROR 1536 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at com.example.SpringBootJpaMysqlComplexApplication.main(SpringBootJpaMysqlComplexApplication.java:23) [classes/:na]
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy110.findByYearAndSumAndHaving(Unknown Source) ~[na:na]
at com.example.SpringBootJpaMysqlComplexApplication.run(SpringBootJpaMysqlComplexApplication.java:39) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
... 5 common frames omitted
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:67) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.getResultSet(Loader.java:2292) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2050) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:953) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2815) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2797) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2629) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.Loader.list(Loader.java:2624) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:396) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1396) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1558) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1526) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at org.hibernate.query.Query.getResultList(Query.java:165) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:409) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy117.getResultList(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:126) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:618) ~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
... 14 common frames omitted
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'order0_.orderDate' in 'having clause'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
... 49 common frames omitted
I used below query, but look like Alias is not creating and hence unable to use that.
#Query("SELECT YEAR(o.orderDate) AS YEAR, SUM(od.quantityOrdered * od.priceEach) AS amount FROM Order o "
+ "INNER JOIN o.orderdetails od WHERE o.status='Shipped' GROUP BY YEAR(o.orderDate) HAVING YEAR(o.orderDate) > 2003")
List<Object[]> findByYearAndSumAndHaving();
OrderDetail:
#Entity
#Table(name="orderdetails")
#NamedQuery(name="Orderdetail.findAll", query="SELECT o FROM Orderdetail o")
public class Orderdetail implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private OrderdetailPK id;
#Column(nullable=false)
private short orderLineNumber;
#Column(nullable=false, precision=10, scale=2)
private BigDecimal priceEach;
#Column(nullable=false)
private int quantityOrdered;
//bi-directional many-to-one association to Order
#ManyToOne
#JoinColumn(name="orderNumber", nullable=false, insertable=false, updatable=false)
private Order order;
//bi-directional many-to-one association to Product
#ManyToOne
#JoinColumn(name="productCode", nullable=false, insertable=false, updatable=false)
private Product product;
...
....
}
Here is the example for JPA Criteria API
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ResultDTO> cq = cb.createQuery(ResultDTO.class);
// Define FROM clause
Root<Orderdetail> root = cq.from(Orderdetail.class);
Join<Orderdetail, Order> order = root.join("order", JoinType.INNER);
cq.where(cb.equal(root.get("status"), "Shipped"));
cq.groupBy(root.get("orderDate"));
cq.having(cb.gt(cb.function("YEAR", Integer.class, root.get("orderDate")), 2003));
cq.select(cb.construct(ResultDTO.class,
cb.function("YEAR", Integer.class, root.get("orderDate")),
cb.sum(cb.prod(root.get("quantityOrdered"), order.get("priceEach")))
));
cq.distinct(true);
TypedQuery<ResultDTO> query = entityManager.createQuery(cq).setHint(QueryHints.HINT_READONLY, true);
// Execute query
return query.getResultList();
public class ResultDTO {
private Integer year;
private Long total;
public ResultDTO(Integer year, Long total) {
.....
}
//getter setter
}

Unable to create #Bean of Custom Repository with #PersistenceContext in Spring Batch Tasklet?

I already went through the link : Can we use #Autowired in a Tasklet in Spring Batch?, but still I am facing the below issue:
All My batch jobs are xml based and looks like unable to autowired the CustMstrCustomRepository bean into the Tasklet with the #PersistentContext
ABCDataTasklet.java
#Configuration
#Data
public class ABCDataTasklet implements Tasklet {
#Autowired
private CustMstrCustomRepository custMstrCustomRepository;
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
List<ABCCustomClass> result = custMstrCustomRepository.getData();
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext()
.put("data", result);
return RepeatStatus.FINISHED;
}
}
Error
java.lang.NullPointerException: null
at com.XXX.XXX.batch.tasklet.ABCDataTasklet.execute(ABCDataTasklet.java:29) ~[classes/:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:272) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:66) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:308) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:141) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134) [spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at com.XXX.jobLauncherService.BillingBatchJobLauncher.executeBillingJob(BillingBatchJobLauncher.java:30) [classes/:na]
at com.mastercard.jpaApplication.run(jpaApplication.java:26) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1258) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at com.mastercard.jpaApplication.main(jpaApplication.java:21) [classes/:na]
2018-08-11 22:33:51.756 INFO 1808 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=ABCDataBatchJob]] completed with the following parameters: [{runMode=YYYY, date=1534007031631, time=1534007031631}] and the following status: [FAILED]
2018-08-11 22:33:51.757 INFO 1808 --- [ Thread-5] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#5bfa9431: startup date [Sat Aug 11 22:33:40 IST 2018]; root of context hierarchy
2018-08-11 22:33:51.758 INFO 1808 --- [ Thread-5] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2018-08-11 22:33:51.759 INFO 1808 --- [ Thread-5] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans
2018-08-11 22:33:51.762 INFO 1808 --- [ Thread-5] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'devcloud'
2018-08-11 22:33:51.763 INFO 1808 --- [ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2018-08-11 22:33:53.923 INFO 1808 --- [ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
CustMstrCustomRepositoryImpl.java
#Service
#Transactional(readOnly = true)
public class CustMstrCustomRepositoryImpl implements CustMstrCustomRepository {
private static final String SQL = "COMPLEX SQL QUERY";
#PersistenceContext
#Qualifier(value = "entityManagerFactory")
private EntityManager entityManager;
#SuppressWarnings("unchecked")
#Override
public List<ABCCustomClass> getData() {
Query q = entityManager.createNativeQuery(SQL);
q.setParameter("actv_sw", "Y");
List<Object[]> resultList = q.getResultList();
List<ABCCustomClass> results = new ArrayList<>();
for (Object[] objects : resultList) {
results.add(ABCCustomClass.builder()
.YY((BigDecimal) objects[0])
.YY((BigDecimal) objects[1])
.YY((Date) objects[2])
.YY((Date) objects[3])
.YY((String) objects[4]).build());
}
return results;
}
}
Can you confirm if the custom repository is defined under a package that is scanned for Bean creation?
Generally this is a configuration given as part of the Application.java
As far as I remember an issue with autowire giving back a null could be because spring was unable to scan the class.
I was able to solved this issue by using #PostContruct annotation and added below logic in #Configuration class.
Now using this way, I can pass the #EntityManager easily now
#Configuration
#ComponentScan("com.XXXX")
#EnableBatchProcessing
#PropertySource("classpath:database.properties")
#ImportResource({ "classpath:jobs/XY.xml"})
#EnableJpaRepositories(basePackages = {"com.XX.repository"})
public class MyConfig {
private PlatformTransactionManager transactionManager;
#PostConstruct
void initialize() throws Exception {
if (this.transactionManager == null) {
this.transactionManager = new ResourcelessTransactionManager();
}
}
}

Resources