0.5.x to 0.6.x
0.6.0 fixes two startup failures and adds two extension points to the HTTP filter. For most applications the upgrade is the version bump. Check these:
- Drop the Actuator workaround. With Spring Boot Actuator on the classpath the starter
failed with
NoUniqueBeanDefinitionExceptiononRequestMappingHandlerMapping. It now injects Spring MVC’s mapping by name, so a@Primaryadded to work around it is no longer needed. - No more
spring-boot-sqlrequirement. An application using the Redis or in-memory store failed at startup withNoClassDefFoundError: DatabaseInitializationMode.idempotency.jdbc.initialize-schemakeeps its values and default, but code callingIdempotencyProperties.Jdbc.getInitializeSchema()now gets the starter’s ownIdempotencyProperties.SchemaInitializationenum. FailurePhasegainsRELEASE. An exhaustiveswitchover it needs a new case.- Listeners can see
onReleased, but only once you declare a storage policy. A listener that cleans up in its terminal callbacks must handle it then; see lifecycle callbacks. - The in-flight
Retry-Afteris shorter. It is now the request’swaitTimeout, or the holder’s remaining lease when that is shorter, instead of the whole remaining lease. Expect clients to retry sooner; see the HTTP reference.
New and optional: a ResponseStoragePolicy bean
releases the key for responses
that mean nothing happened, and an IdempotencyRejectionHandler bean
renders the filter’s own rejections in your
API’s error format. Without either, behaviour is unchanged.
Records written by 0.5.x remain readable; the stored format did not change.
0.4.x to 0.5.x
0.5.0 makes completions follow the caller’s transaction: nothing is recorded as complete until the work commits, and a rollback frees the key. For most applications the upgrade is the version bump. Check these:
- An
IdempotentAdvisorbean now fails startup. The starter no longer registers one. Remove yours; without the starter, registerIdempotentBeanPostProcessorinstead. An@EnableTransactionManagement(order = ...)kept for joined completion is no longer needed, and harmless if it stays. - A custom transactional store must override
completeInTransaction. Joined completion now calls it, andcompletealways means a write of its own. A store that cannot join a transaction needs no change. See writing a store. - Inside a transaction, the record is written after the commit.
onCompletedfires then, and a rollback firesonFailedwithFailurePhase.ROLLBACKand frees the key at once. Listeners that assumedonCompletedfired before the commit need a look. - The same key twice in one transaction no longer replays. The second call reports in
flight; see joining your transaction for the
noRollbackForthat keeps a batch alive. - Size the connection pool above the number of concurrent transactional
@Idempotentcalls - see annotated methods.
Records written by 0.4.x remain readable; the stored format did not change.
0.3.x to 0.4.x
0.4.0 moved to Spring Boot 4 and Spring Framework 7.
Spring Boot 3.5 reached open source end of life on 30 June 2026, and 3.5.16 was its final OSS patch, so the 3.x line no longer receives fixes from Spring itself.
If you are moving off 0.3.x, the move is a Spring Boot 4 migration first. Upgrade Boot, then the coordinate:
<dependency>
<groupId>io.github.josipmusa</groupId>
<artifactId>idempotency-spring-boot-starter</artifactId>
<version>0.6.0</version>
</dependency>Records written by 0.3.x remain readable; the stored format did not change.
There are no versioned docs
These pages document the current release. A library at this size with one supported line does not need a version switcher, and an upgrade page that states what changed is more useful than a frozen copy of the previous release’s prose.
The authoritative per-release detail is the library’s CHANGELOG.md.
Checking what you are on
The starter logs the selected store at startup. The artifact version is whatever your build file pins; the BOM keeps the modules on one version, which is the failure worth avoiding when upgrading several at once.