Annotation Interface HandleDocument


@Documented @Retention(RUNTIME) @Target({METHOD,CONSTRUCTOR}) @HandleMessage(DOCUMENT) public @interface HandleDocument
Marks a method or constructor as a handler for document messages within a search collection.

This is a specialization of HandleMessage for MessageType.DOCUMENT messages. It allows consuming updates from the document store in near real-time—similar to event tracking. Handlers can either specify a collection name, a document class, or the materialized graph projection of an independent model.

Document Tracking Semantics

Each time a document is (re)indexed in Fluxzero, it receives a new tracking index. When a handler is subscribed via @HandleDocument, it will receive the most recent version of the document for each index. If the tracker is behind (e.g., during a replay), earlier versions of the same document may be skipped—only the latest version is retained.

Transforming and Updating Documents

A powerful feature of document handlers is that they can return a modified version of the document to update it in-place. This allows document transformations and upcasting to be applied automatically and reliably.

For this behavior to take effect:

  • The returned document must have a higher Revision than the one stored
  • The updated version will be stored in the document collection under the same ID

This mechanism supports fully-automated data migrations: handlers can evolve or patch documents over time, and changes are persisted across application restarts.

See Also:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    boolean
    If true, disables this handler during discovery.
    Optional class of the documents to handle.
    Optional independent-model root whose materialized graph projection should be handled.
    Selects the verified internal current-state source of a Model, rather than its independent DOCUMENT projection.
    Determines how the handler responds when referenced protected data is no longer available.
    Optional name of the document collection.
  • Element Details

    • onMissingProtectedData

      MissingProtectedDataPolicy onMissingProtectedData
      Determines how the handler responds when referenced protected data is no longer available.
      Default:
      DEFAULT
    • value

      String value
      Optional name of the document collection. If provided, documentClass() is ignored.

      If neither documentClass nor value are specified, the first parameter of the method is used to determine the collection:

      class OrganisationHandler {
          @HandleDocument
          void on(Organisation organisation, Metadata metadata) { ... }
      }
      
      See Also:
      Default:
      ""
    • documentClass

      Class<?> documentClass
      Optional class of the documents to handle. If annotated with Searchable, the annotation defines the collection; otherwise the class name is used.

      If neither documentClass nor value are specified, the first parameter of the method is used to determine the collection:

      class OrganisationHandler {
          @HandleDocument
          void on(Organisation organisation, Metadata metadata) { ... }
      }
      
      See Also:
      Default:
      java.lang.Void.class
    • modelGraph

      Class<?> modelGraph
      Optional independent-model root whose materialized graph projection should be handled.

      The model must enable Model.materializeGraph(). The effective collection is resolved from Model.graphProjection(), including its derived Graph-collection default and any explicit collection override. A handler may inject Graph<RootModel>; node values are materialized lazily and parent, root, child and descendant navigation stays within the projected state boundary. This is useful when a stateful document handler needs to maintain a local view over complete model graphs rather than over independently stored root documents.

      When a materialized root graph is deleted, this handler receives a typed empty graph. The graph retains its identity, type and deletion boundary, while previous() returns the complete last materialized graph. Deletion records are exclusive to handlers using modelGraph; ordinary document handlers for the same collection do not receive them.

      A non-passive handler may return the injected complete Graph<RootModel> to persist ordinary serializer upcasting of its root and descendants into the materialized projection. Every node retains its own serialized type and revision and uses the ordinary @Upcast chain; there is no Graph-wide upcaster. Register a type alias as well when a node's Java type name changes, even if its content upcaster returns a Data<T> envelope with the new name: the replacement guard needs a content-independent type mapping. Root upcasting must yield exactly one state; split/drop upcasters remain available to ordinary document handlers, but cannot split or silently remove a materialized Graph. This is a projection-only migration: the graph must retain the handled root, state boundary, nodes and placements, and direct Models, relationships and projection progress are never changed. The Runtime replaces the document only if its original manifest is still current, so a delayed handler cannot overwrite a newer projection. Returning a Graph whose node schemas are already current is a no-op; tombstones remain observational.

      An explicit value() takes precedence. Otherwise this attribute takes precedence over documentClass() and inference from the first handler parameter.

      Default:
      java.lang.Void.class
    • modelState

      Class<?> modelState
      Selects the verified internal current-state source of a Model, rather than its independent DOCUMENT projection. Return the injected upcast Model value unchanged to persist a schema migration. The source must already be maintained (DOCUMENT persistence, an explicit composition path, or a materialized Graph). A schema rewrite preserves identity, Model head, relationships and event history; null or business-state changes are rejected. Upcasting must produce exactly one state, and rewriting requires a higher serialized revision. A custom DocumentSerializer must support its logical-state snapshot operation. Concurrent state changes, deletion, erasure or another schema rewrite make an old rewrite a no-op. Public document and materialized Graph projections are reindexed independently. Use normal Model commands for business changes. A void handler only observes. This selector cannot be combined with an explicit collection, documentClass() or modelGraph().
      Default:
      java.lang.Void.class
    • disabled

      boolean disabled
      If true, disables this handler during discovery.
      Default:
      false