1616
1717package org .springframework .batch .core .repository .dao .jdbc ;
1818
19- import java .sql .PreparedStatement ;
20- import java .sql .SQLException ;
19+ import java .sql .ResultSet ;
2120import java .sql .Timestamp ;
2221import java .sql .Types ;
2322import java .util .ArrayList ;
2423import java .util .Arrays ;
25- import java .util .Collection ;
26- import java .util .Comparator ;
27- import java .util .Iterator ;
2824import java .util .List ;
2925import java .util .concurrent .locks .Lock ;
3026import java .util .concurrent .locks .ReentrantLock ;
4137import org .springframework .batch .core .repository .dao .StepExecutionDao ;
4238import org .springframework .beans .factory .InitializingBean ;
4339import org .springframework .dao .OptimisticLockingFailureException ;
44- import org .springframework .jdbc .core .BatchPreparedStatementSetter ;
40+ import org .springframework .jdbc .core .PreparedStatementCallback ;
4541import org .springframework .jdbc .support .incrementer .DataFieldMaxValueIncrementer ;
4642import org .jspecify .annotations .Nullable ;
4743import org .springframework .util .Assert ;
@@ -99,6 +95,7 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao implement
9995 FROM %PREFIX%JOB_EXECUTION JE
10096 JOIN %PREFIX%STEP_EXECUTION SE ON SE.JOB_EXECUTION_ID = JE.JOB_EXECUTION_ID
10197 WHERE JE.JOB_INSTANCE_ID = ? AND SE.STEP_NAME = ?
98+ ORDER BY SE.CREATE_TIME DESC, SE.STEP_EXECUTION_ID DESC
10299 """ ;
103100
104101 private static final String CURRENT_VERSION_STEP_EXECUTION = """
@@ -124,10 +121,6 @@ SELECT COUNT(*)
124121 WHERE SE.STEP_EXECUTION_ID = ? AND JE.JOB_EXECUTION_ID = SE.JOB_EXECUTION_ID
125122 """ ;
126123
127- private static final Comparator <StepExecution > BY_CREATE_TIME_DESC_ID_DESC = Comparator
128- .comparing (StepExecution ::getCreateTime , Comparator .reverseOrder ())
129- .thenComparing (StepExecution ::getId , Comparator .reverseOrder ());
130-
131124 private int exitMessageLength = DEFAULT_EXIT_MESSAGE_LENGTH ;
132125
133126 private DataFieldMaxValueIncrementer stepExecutionIncrementer ;
@@ -317,28 +310,35 @@ public StepExecution getStepExecution(JobExecution jobExecution, long stepExecut
317310 }
318311 }
319312
313+ @ Nullable
320314 @ Override
321315 public StepExecution getLastStepExecution (JobInstance jobInstance , String stepName ) {
322- List <StepExecution > executions = getJdbcTemplate ().query (getQuery (GET_LAST_STEP_EXECUTION ), (rs , rowNum ) -> {
323- long jobExecutionId = rs .getLong (19 );
324- JobExecution jobExecution = new JobExecution (jobExecutionId , jobInstance ,
325- jobExecutionDao .getJobParameters (jobExecutionId ));
326- jobExecution .setStartTime (rs .getTimestamp (20 ) == null ? null : rs .getTimestamp (20 ).toLocalDateTime ());
327- jobExecution .setEndTime (rs .getTimestamp (21 ) == null ? null : rs .getTimestamp (21 ).toLocalDateTime ());
328- jobExecution .setStatus (BatchStatus .valueOf (rs .getString (22 )));
329- jobExecution .setExitStatus (new ExitStatus (rs .getString (23 ), rs .getString (24 )));
330- jobExecution .setCreateTime (rs .getTimestamp (25 ) == null ? null : rs .getTimestamp (25 ).toLocalDateTime ());
331- jobExecution .setLastUpdated (rs .getTimestamp (26 ) == null ? null : rs .getTimestamp (26 ).toLocalDateTime ());
332- jobExecution .setVersion (rs .getInt (27 ));
333- return new StepExecutionRowMapper (jobExecution ).mapRow (rs , rowNum );
334- }, jobInstance .getInstanceId (), stepName );
335- executions .sort (BY_CREATE_TIME_DESC_ID_DESC );
336- if (executions .isEmpty ()) {
337- return null ;
338- }
339- else {
340- return executions .get (0 );
341- }
316+ return getJdbcTemplate ().execute (getQuery (GET_LAST_STEP_EXECUTION ),
317+ (PreparedStatementCallback <StepExecution >) statement -> {
318+ statement .setMaxRows (1 );
319+ statement .setLong (1 , jobInstance .getInstanceId ());
320+ statement .setString (2 , stepName );
321+ try (ResultSet rs = statement .executeQuery ()) {
322+ if (rs .next ()) {
323+ Long jobExecutionId = rs .getLong (19 );
324+ JobExecution jobExecution = new JobExecution (jobExecutionId , jobInstance ,
325+ jobExecutionDao .getJobParameters (jobExecutionId ));
326+ jobExecution .setStartTime (
327+ rs .getTimestamp (20 ) == null ? null : rs .getTimestamp (20 ).toLocalDateTime ());
328+ jobExecution
329+ .setEndTime (rs .getTimestamp (21 ) == null ? null : rs .getTimestamp (21 ).toLocalDateTime ());
330+ jobExecution .setStatus (BatchStatus .valueOf (rs .getString (22 )));
331+ jobExecution .setExitStatus (new ExitStatus (rs .getString (23 ), rs .getString (24 )));
332+ jobExecution .setCreateTime (
333+ rs .getTimestamp (25 ) == null ? null : rs .getTimestamp (25 ).toLocalDateTime ());
334+ jobExecution .setLastUpdated (
335+ rs .getTimestamp (26 ) == null ? null : rs .getTimestamp (26 ).toLocalDateTime ());
336+ jobExecution .setVersion (rs .getInt (27 ));
337+ return new StepExecutionRowMapper (jobExecution ).mapRow (rs , 0 );
338+ }
339+ return null ;
340+ }
341+ });
342342 }
343343
344344 /**
0 commit comments