Skip to main content
This page is the focused reference for all supported handler method signatures. For dispatch semantics, multi-annotation combinations, and validation errors, see Event Handlers.

Parameter Styles

Typed handlers (@OnInsert, @OnUpdate, @OnDelete, @OnReplace) support three parameter styles. @OnChange supports only CONTEXT_ONLY.
StyleParametersNotes
CONTEXT_ONLY(ChangeStreamContext<T> ctx)Access metadata + document via ctx.getFullDocument().
DOCUMENT_ONLY(T doc)Receive the deserialized document directly. Requires a concrete documentType.
DOCUMENT_AND_CONTEXT(T doc, ChangeStreamContext<T> ctx)Both the document and the context. Requires a concrete documentType.
DOCUMENT_ONLY and DOCUMENT_AND_CONTEXT signatures fail at startup with BeanCreationException if @ChangeStream.documentType is Document.class (the default). Set a concrete class:
@ChangeStream(documentType = Order.class)

Return Types — Mode Exclusivity

The return type is bound to the configured execution mode (flowwarden.default-mode):
ModeRequired return typeOther return types
IMPERATIVE (default)voidMono<Void> is rejected at startup
REACTIVEMono<Void>void is rejected at startup
Mixing return types across handlers in the same application is not allowed. All handler methods must consistently return void or Mono<Void> matching the configured mode. A mismatch triggers a BeanCreationException.
Other return types — CompletableFuture, Flux, String, etc. — are rejected at startup with unsupported return type.

Full Signature Matrix

StyleSignature
CONTEXT_ONLYvoid handle(ChangeStreamContext<T> ctx)
DOCUMENT_ONLYvoid handle(T doc)
DOCUMENT_AND_CONTEXTvoid handle(T doc, ChangeStreamContext<T> ctx)
For @OnChange: only void handle(ChangeStreamContext<T> ctx) is allowed.

Examples

CONTEXT_ONLY

@OnUpdate
void onUpdate(ChangeStreamContext<Order> ctx) {
    Optional<Order> order = ctx.getFullDocument(Order.class);
    log.info("Order updated: {}", ctx.getDocumentKey());
}

DOCUMENT_ONLY

@OnInsert
void onInsert(Order doc) {
    log.info("New order: {}", doc.getId());
}

DOCUMENT_AND_CONTEXT

@OnInsert
void onInsert(Order doc, ChangeStreamContext<Order> ctx) {
    log.info("Order {} created, attempt #{}", doc.getId(), ctx.getAttemptNumber());
}

Reactive variants

@OnInsert
Mono<Void> onInsertReactive(Order doc, ChangeStreamContext<Order> ctx) {
    return orderService.processReactive(doc);
}

Injecting Other Beans

Need a MongoTemplate, a custom service, or any other Spring bean? Inject it through the handler class (constructor or @Autowired field), not via the handler method signature:
@ChangeStream(documentType = Order.class)
public class OrderHandler {

    private final MongoTemplate mongoTemplate;
    private final BillingService billing;

    public OrderHandler(MongoTemplate mongoTemplate, BillingService billing) {
        this.mongoTemplate = mongoTemplate;
        this.billing = billing;
    }

    @OnInsert
    void onInsert(Order doc, ChangeStreamContext<Order> ctx) {
        billing.charge(doc);
        mongoTemplate.save(doc, "processed_orders");
    }
}
The handler class is a regular Spring @Component (via @ChangeStream’s meta-annotation), so all standard Spring injection patterns apply.

DELETE handler caveat

For DELETE events, MongoDB does not provide a fullDocument. If you use DOCUMENT_ONLY or DOCUMENT_AND_CONTEXT on @OnDelete, the doc parameter will be null at runtime:
@OnDelete
void onDelete(Order doc, ChangeStreamContext<Order> ctx) {
    // doc is ALWAYS null here
}
Prefer CONTEXT_ONLY for @OnDelete and use ctx.getDocumentKey() to identify the affected document:
@OnDelete
void onDelete(ChangeStreamContext<Order> ctx) {
    log.info("Order deleted: {}", ctx.getDocumentKey());
}

See Also

Event Handlers

Dispatch priority, multi-annotation combinations, validation errors.

@ChangeStream

Parent class annotation — documentType, modes, behavior flags.

ChangeStreamContext

The context object passed to every handler.

@Filter

Application-side filtering and signature constraints with @OnDelete.