From 0d1ba2280d0422c9c6f0a012cbd6849c74cb89f1 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 17 Jun 2021 12:26:23 +0200 Subject: [PATCH] Fix step execution retrieval in SimpleJobExplorer#getLastJobExecution Before this commit, SimpleJobExplorer#getLastJobExecution returned the last job execution without fetching its step executions and their execution contexts. This commit fixes the implementation to load the entire object graph as done in SimpleJobExplorer#getJobExecution. Issue #3943 --- .../explore/support/SimpleJobExplorer.java | 11 +++++-- .../SimpleJobExplorerIntegrationTests.java | 29 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java index 81a1d9c333..c9abd7cfac 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2019 the original author or authors. + * Copyright 2006-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,7 +99,14 @@ public List getJobExecutions(JobInstance jobInstance) { */ @Nullable public JobExecution getLastJobExecution(JobInstance jobInstance) { - return jobExecutionDao.getLastJobExecution(jobInstance); + JobExecution lastJobExecution = jobExecutionDao.getLastJobExecution(jobInstance); + if (lastJobExecution != null) { + getJobExecutionDependencies(lastJobExecution); + for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) { + getStepExecutionDependencies(stepExecution); + } + } + return lastJobExecution; } /* diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerIntegrationTests.java index 04a856347f..d7bc8078c6 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import test.jdbc.datasource.DataSourceInitializer; import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobInterruptedException; @@ -32,6 +33,7 @@ import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.UnexpectedJobExecutionException; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.configuration.xml.DummyStep; import org.springframework.batch.core.explore.JobExplorer; @@ -41,6 +43,7 @@ import org.springframework.batch.core.job.flow.support.StateTransition; import org.springframework.batch.core.job.flow.support.state.EndState; import org.springframework.batch.core.job.flow.support.state.StepState; +import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; import org.springframework.batch.core.repository.JobRepository; @@ -54,6 +57,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * Integration test for the BATCH-2034 issue. @@ -63,6 +67,7 @@ * from the spring-batch-integration project. * * @author Sergey Shcherbakov + * @author Mahmoud Ben Hassine */ @ContextConfiguration(classes={SimpleJobExplorerIntegrationTests.Config.class}) @RunWith(SpringJUnit4ClassRunner.class) @@ -127,6 +132,13 @@ public DataSourceInitializer dataSourceInitializer() { }); return dataSourceInitializer; } + + @Bean + public Job job(JobBuilderFactory jobBuilderFactory) { + return jobBuilderFactory.get("job") + .start(dummyStep()) + .build(); + } } @Autowired @@ -137,6 +149,12 @@ public DataSourceInitializer dataSourceInitializer() { @Autowired private FlowStep flowStep; + + @Autowired + private JobLauncher jobLauncher; + + @Autowired + private Job job; @Test public void testGetStepExecution() throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobInterruptedException, UnexpectedJobExecutionException { @@ -153,4 +171,13 @@ public void testGetStepExecution() throws JobExecutionAlreadyRunningException, J assertEquals(BatchStatus.COMPLETED, jobExplorerStepExecution.getStatus()); } + @Test + public void getLastJobExecutionShouldFetchStepExecutions() throws Exception { + this.jobLauncher.run(this.job, new JobParameters()); + JobInstance lastJobInstance = this.jobExplorer.getLastJobInstance("job"); + JobExecution lastJobExecution = this.jobExplorer.getLastJobExecution(lastJobInstance); + assertEquals(1, lastJobExecution.getStepExecutions().size()); + StepExecution stepExecution = lastJobExecution.getStepExecutions().iterator().next(); + assertNotNull(stepExecution.getExecutionContext()); + } }