What is the difference between identifying and non-identifying JobParameters, and how does it affect JobInstance identity?
answer
- identity = job name + identifying params
- default identifying = true
- addString(k,v,false) => non-identifying
- same identifying params => same JobInstance
- restart needs same identifying params
basics
~10 sIdentifying parameters (the default) contribute to a JobInstance's identity — the same set means the same instance. Non-identifying parameters are ignored when computing identity, so you can change them without creating a new instance.
solid answer
~40 sA JobInstance represents a logical run of a job for a specific set of inputs, and its identity is derived from the job name plus the identifying JobParameters. By default every parameter is identifying: two launches with identical identifying parameters resolve to the same JobInstance, and if that instance already completed you get JobInstanceAlreadyCompleteException. Marking a parameter non-identifying (e.g., addString("key","val", false) — the boolean identifying flag) excludes it from the identity hash, so it's still persisted and injectable but doesn't distinguish instances. Typical use: businessDate is identifying (defines the logical run), while runTimestamp or a debug flag is non-identifying. This matters for restart semantics: restarting a failed job must supply the same identifying parameters so Spring Batch finds the existing incomplete JobInstance and resumes it rather than starting fresh.
code
java · 12 lines// businessDate defines the logical run (identifying);
// triggeredBy is bookkeeping only (non-identifying).
JobParameters params = new JobParametersBuilder()
.addLocalDate("businessDate", LocalDate.of(2026, 7, 1)) // identifying
.addString("triggeredBy", "nightly-scheduler", false) // non-identifying
.toJobParameters();
try {
jobLauncher.run(ordersJob, params);
} catch (JobInstanceAlreadyCompleteException e) {
// Same identifying params already completed -> duplicate run blocked.
}go deeper
Know the default is identifying and matching params means the same instance.
Explain the identifying flag, the builder overload, and duplicate-run protection.
Tie it to restart semantics and JOB_KEY hashing in metadata tables.
Design parameter schemes (business key identifying, volatile bookkeeping non-identifying) for idempotent, restartable pipelines.
## Core concepts A **`JobInstance`** is the logical, unique execution of a job for one set of inputs — for example, "the orders job for business date 2026-07-01". A **`JobExecution`** is a single physical attempt at running a `JobInstance`; one `JobInstance` can have many `JobExecution`s (each retry/restart is a new execution). `JobInstance` **identity** = **job name + identifying JobParameters**. Spring Batch computes this and stores it (`BATCH_JOB_INSTANCE`, with a `JOB_KEY` hash of the identifying parameters). ## Identifying vs non-identifying Each `JobParameter` carries a boolean **`identifying`** flag. - **Identifying (default true):** the parameter participates in the identity hash. Change it and you get a *different* `JobInstance`. - **Non-identifying (false):** the parameter is still stored and still injectable via SpEL, but it is **excluded** from identity computation. Change it and you stay on the *same* `JobInstance`. You set it with the builder overloads: ```java new JobParametersBuilder() .addLocalDate("businessDate", date) // identifying (default) .addString("triggeredBy", "scheduler", false) // non-identifying .toJobParameters(); ``` ## Why it matters ### 1. Duplicate-run protection Launching a job whose identifying parameters match an **already completed** `JobInstance` throws `JobInstanceAlreadyCompleteException`. This is a feature: a batch job for a given business date should not silently run twice. ### 2. Restart semantics To **restart** a *failed/stopped* execution, you relaunch with the **same identifying parameters**. Spring Batch finds the existing incomplete `JobInstance` and creates a new `JobExecution` that resumes from the last checkpoint. If your run-uniqueness came from an *identifying* timestamp, you could never restart (every launch is a new instance). If it came from a *non-identifying* timestamp, you can vary it freely and still restart. ### 3. Repeatable scheduling A common pattern: make the meaningful business key identifying, and put volatile bookkeeping (wall-clock time, trigger source) as non-identifying — or use a `JobParametersIncrementer` to bump an identifying `run.id`. ## Gotchas - Non-identifying parameters **are** persisted and **are** available for late-binding; "non-identifying" only means "ignored for identity", not "not stored". - Removing a parameter vs. marking it non-identifying are different: removing changes the parameter set; marking non-identifying keeps it but excludes it from the hash. - Type is part of identity too — `addLong("id",1L)` and `addString("id","1")` are different identities. - Empty/whitespace differences in string values produce different identities.
- If a job failed, how do you restart it correctly?Relaunch with the same identifying JobParameters. Spring Batch locates the existing incomplete JobInstance and starts a new JobExecution that resumes from the last successful checkpoint, rather than creating a fresh instance.
- Are non-identifying parameters persisted and injectable?Yes. Non-identifying only excludes them from JobInstance identity. They are stored in BATCH_JOB_EXECUTION_PARAMS and remain available via @Value SpEL late binding.
saying these in an interview costs you the question
- Claiming non-identifying parameters are not stored at all
- Saying every launch always creates a new JobInstance regardless of parameters
- Thinking you can restart a failed job with different identifying parameters