0

I need to implement two different jobs, and choose which one of them I want to run, but I currently can't, it is giving me the following error:

Field processJob in JobInvokerController required a single bean, but 2 were found:

  • procesaClientesJob: defined by method 'procesaClientesJob' in class path resource [BatchConfig.class]
  • procesaParcialClientesJob: defined by method 'procesaParcialClientesJob' in class path resource [BatchConfig.class]

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

My BatchConfig.java is like:

[....]

@Bean
    Job procesaClientesJob(JobBuilderFactory jobBuilderFactory,
                           @Qualifier("flowCargaIdsClientes") Flow flowCargaIdsClientes,
                           @Qualifier("flowCargaDatosClientes") Flow flowCargaDatosClientes,
                           @Qualifier("flowCargaParcialIdsClientes") Flow flowCargaParcialIdsClientes,
                           @Qualifier("flowCargaParcialDatosClientes") Flow flowCargaParcialDatosClientes
                           ) {
        return jobBuilderFactory.get("procesaClientesJob")
                .incrementer(new RunIdIncrementer())
                .start(flowCargaIdsClientes).next(flowCargaDatosClientes).end()
                .build();
    }

    
    @Bean
    Job procesaParcialClientesJob(JobBuilderFactory jobBuilderFactory,
                           @Qualifier("flowCargaParcialIdsClientes") Flow flowCargaParcialIdsClientes,
                           @Qualifier("flowCargaParcialDatosClientes") Flow flowCargaParcialDatosClientes
                           ) {
        return jobBuilderFactory.get("procesaClientesJob")
                                .incrementer(new RunIdIncrementer())
                                .start(flowCargaParcialIdsClientes).next(flowCargaParcialDatosClientes).end()
                                .build();
    }

My class JobInvokeController.java is like:

@RestController
public class JobInvokerController {
    private static final Logger log = Logger.getLogger(JobInvokerController.class);
    
    @Autowired
    JobLauncher jobLauncher;
 
    @Autowired
    Job processJob;
 
    @GetMapping("/invokejob/{strFecha}")
    public String invokejob(@PathVariable String strFecha) throws Exception {
        Date fecha;
        if (log.isDebugEnabled()) {
            log.debug("Procesamos el parámetro de entrada " + strFecha);
        }

        try {
            if (!StringUtils.isEmpty(strFecha)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                fecha = sdf.parse(strFecha);
            } else {
                fecha = new Date();
            }
        } catch (Exception e) {
            fecha = new Date();
        }

        if (log.isDebugEnabled()) {
            log.debug("Invocamos al batch con la fecha: " + fecha);
        }
        
        JobParameters jobParameters = new JobParametersBuilder().addLong("time",System.currentTimeMillis()).addDate("fecha", fecha).toJobParameters();
        jobLauncher.run(processJob, jobParameters);
 
        return "Batch job has been invoked";
    }
    
}

And I also have a SpringBatchApplication.java:

@SpringBootApplication
public class SpringBatchApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBatchApplication.class, args);
    }
}

How can I have two simultaneous jobs and choose what I want to run?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Julia
  • 538
  • 2
  • 7
  • 17

1 Answers1

1

When do you want to choose the job you want to run? If it's before the application starts I would recommend using profiles and then activating the profile for the job you want to run (-Dspring.profiles.active=job1) Or if you want to choose during run-time then just @Autowire both of your jobs you can use qualifiers like described here: Spring @Autowired and @Qualifier

  • I want to choose it during runtime. If it's possible, I would like to have two different @GetMapping methods, and each one execute one different job. How can I do it? – Julia Nov 30 '17 at 12:57
  • you don't actually need that, just use one: `@GetMapping("/invokejob/{jobId}/{strFecha}")` and then in the method have an ```if ("job1".equals(jobId) {} else {}``` statement that would choose which job to run. Just a reminder - you need to autowire both your beans (and using the @Qualifier to allow the container to distinguish between them) – Anatolie Lupacescu Nov 30 '17 at 13:00
  • Here's what I am trying to say: https://gist.github.com/anatollupacescu/924bb63326e4f6d845bdc8be772149ed, feel free to comment directly on github. – Anatolie Lupacescu Nov 30 '17 at 13:21