@OnChange, @OnInsert, @OnUpdate, @OnDelete, or @OnReplace. These annotations go on methods inside a @ChangeStream class.
Overview
There are two types of handler annotations:Dispatch Priority
When an event arrives, FlowWarden resolves the handler in this order:- Typed handler matching the operation type (
@OnInsertfor INSERT,@OnUpdatefor UPDATE, etc.) @OnChangefallback — invoked for every operation that is not covered by a typed handler, includingDROPandINVALIDATE
Typed handlers always take priority.
@OnChange is only invoked for operation types that have no dedicated typed handler in the class.@OnChange
Generic handler for all Change Stream event types. Acts as a catch-all when no typed handler matches.- Only one
@OnChangemethod is allowed per@ChangeStreamclass. - The annotation takes no attributes — it is a pure catch-all.
- Signature must use the
CONTEXT_ONLYstyle —void handle(ChangeStreamContext ctx)orMono<Void> handle(ChangeStreamContext ctx).
Typed Handlers
@OnInsert
Called when a new document is inserted into the collection.@OnUpdate
Called when an existing document is updated.@OnDelete
Called when a document is deleted.@OnReplace
Called when a document is replaced entirely (e.g. viaMongoTemplate.save() on an existing document).
Rules for Typed Handlers
- At most one method per typed annotation per class (e.g. you cannot have two
@OnInsertmethods) - If no typed handler matches the event,
@OnChangeis used as fallback (if present) - If neither a typed handler nor
@OnChangematches, the event is silently skipped
Combining Annotations on the Same Method
You can place multiple typed annotations on a single method to handle several operation types with the same logic:@OnChange if a catch-all is also declared in the same class.
Handling a subset of operations
Handling a subset of operations
@OnChange is a catch-all only — it cannot be narrowed to specific operation types. To target a subset (e.g. INSERT and UPDATE only), declare typed handlers that delegate to a shared helper:Supported Signatures
Parameter Styles
Typed handler methods (@OnInsert, @OnUpdate, @OnDelete, @OnReplace) support three parameter styles:
@OnChange only supports CONTEXT_ONLY.
Return Types — Mode Exclusivity
Handler methods must use the return type that matches the configuredflowwarden.default-mode:
This gives the following full signature matrix:
- Imperative (void)
- Reactive (Mono)
CompletableFuture, Flux, String) is rejected at startup.
Examples
Typed Handlers with @OnChange Fallback
This example handles INSERT, UPDATE, and DELETE with typed handlers, and uses@OnChange as a fallback for REPLACE events.
Combined Annotations with @Filter
From thesample-spring-mvc module — a handler that reacts to both INSERT and UPDATE with a client-side filter:
This works because both INSERT and UPDATE events have a
fullDocument available, which is required by @Filter. Combining @OnInsert @OnDelete with @Filter would fail at startup because DELETE events have no full document.Minimal — Single @OnChange
The simplest form: one handler for all event types.Event Capture for Testing
From theflowwarden-samples project — a reusable handler that captures events for test assertions:
Validation Errors
FlowWarden validates handler methods at startup. Here are the common errors:See Also
@ChangeStream
The parent annotation that declares a Change Stream handler class.
Handler Signatures
Detailed reference for all supported method signatures.
ChangeStreamContext
The context object passed to every handler — access document, metadata, and operations.
@Filter
Server-side filtering to reduce the events reaching your handlers.