I have a requirement of sending a Custom Object to the Spring Batch Job , where this Object is used continuously used by the Item Processor for the business requirement.
How can we send custom object from outside to the Job Context. This Object changes from Job to Job and generated at runtime depending on Business case.
How can send this as a Job Parameter? or is there any way that i can set this Object to the respective Job ?
can overriding Spring JobParameter help me in any way? or are there any Big issues as an outcome of this Overriding behaviour ?
This question has been asked on the offical Spring Batch forum : http://forum.spring.io/forum/spring-projects/batch/96660-how-to-pass-complex-objects-to-job-launcher
A Jira was open then but the developpers chose not to resolve it (Won't fix
) : https://jira.spring.io/browse/BATCH-966
An alternative solution for a more or less identical case (passing a stream as a JobParameter) was discussed here : Passing stream to job as parameter
To summarize, the answer is no you can only pass primitive types as JobParameters and overriding it seems to be discouraged. The alternative solutions are to either declare and inject a Bean with your parameters or to use a static variable to access it project-wide.
I have summarized reasons why you cannot send object as JobParameter
in this question. There are couple of ideas on that question how you can do it.
TL:TR: I think best way would be either to create table in DB which stores Object and pass id of that record as JobParameter or to serialize Object to json and pass it as String in job as JobParameter. If you go with second option be aware that string_val is stored in DB as varchar 250 so limit is 250 characters.
You would use ThreadLocal before init the job execution, there is a tutorial in spanish about how to use ThreadLocal:
http://aquiseprograma.co/2015/09/como-pasar-variables-o-valores-entre-metodos-sin-que-sea-como-parametro-dentro-del-mismo-hilo-de-ejecucion-en-java-threadlocal/
I've found a way just if your string parameter length is fixed, but it is greater than 250. Just split it into pieces of 250, then, within the XML configuration use Spring EL in this way:
Set your parameter in your main Class like this:
JobParametersBuilder parametersBuilder = new JobParametersBuilder();
parametersBuilder.addString("useful.parameter.1", headers.substring(0, 250));
parametersBuilder.addString("useful.parameter.2", headers.substring(250, 500));
parametersBuilder.addString("useful.parameter.3", headers.substring(500, headers.length()));
Configure your parameters and the scope in "step":
<bean id="someStep01Writer" class="path.to.some.StepWriter" scope="step">
<property name="someUsefulProperty" value="#{jobParameters['useful.parameter.1'] + jobParameters['useful.parameter.2'] + jobParameters['useful.parameter.3']}"/>
</bean>
Hope it helps.
Use the below class to send CustomObject.
public static class CustomJobParameter<T extends Serializable> extends JobParameter {
private T customParam;
public CustomJobParameter(T customParam){
super(UUID.randomUUID().toString());//This is to avoid duplicate JobInstance error
this.customParam = customParam;
}
public T getValue(){
return customParam;
}
}
===========================
Usage:
Sending parameter:
JobParameters paramJobParameters = new JobParametersBuilder().addParameter("customparam", new CustomJobParameter<MyClass>(myClassReference)).toJobParameters();
Retrieving parameter:
MyClass myclass = (MyClass)jobExecution.getJobParameters().getParameters().get("customparam").getValue();