Annotation Interface Parent
Choose which relationships belong in the Graph first, then choose each relationship's deletion policy.
A plain typed Id without this annotation stores a reference but registers no Graph edge.
This annotation defaults to cascade deletion; @Parent(deleteOnParentDeletion = false) expresses a
normal non-owning Graph relation. For example, a LineItem can have an owning @Parent OrderId orderId
and a non-owning @Parent(deleteOnParentDeletion = false) ProductId productId: deleting the order
deletes the line, whereas deleting the product does not.
On a scheduled message or command payload, this also declares schedule ownership: deletion of any referenced,
already committed Model asynchronously cancels the schedule. Applicable @Apply returns of null,
cascaded deletion and hard erasure all invalidate ownership. Null references and
deleteOnParentDeletion = false do not own the schedule. The schedule is not a Model or Graph node;
pathInParent and apiDoc do not compose it. Already delivered work cannot be recalled.
Explicit Schedule.withParents(Object...) selections override these declarations.
Both sides remain independent model and persistence boundaries. Use a parent relationship when the child has its own
creation, update history, retention, or deletion lifecycle but belongs in the parent's domain graph. Being rendered
below the parent, or being deleted with it by default, does not turn the child into an embedded Member.
A child identifier that is meaningful only below this parent can use EntityId.parentScoped().
A parent reference is stored independently from both model values so changing this property can attach, detach, or
move the child without loading or rewriting either parent. A null value means that the property currently has no
parent. Non-null values use their Object.toString() representation as the referenced model identity.
The parent model type is inferred when the property is an Id<T>. For a String or another
untyped ID, value() may name the parent model explicitly. An explicit type is required only for features
that need parent model metadata, including automatic graph-document composition.
A typed parent may target the declaring model type itself, for example to represent folders within folders.
Concrete relationship cycles are rejected atomically when the relationship change is committed.
pathInParent() is an optional path relative to the parent document. Supplying it opts this edge into
automatic virtual-document stitching and CQRS graph placement. Omitting it leaves relationship navigation and graph
bundles available without silently deriving a durable document path from a Java class name. The path names a
list-valued collection: the runtime appends deterministic numeric child positions, so numeric path segments are not
allowed.
Graph placement is independent from persistence and search activation. This path alone creates no document.
Enable Model.searchable() on the child or on an ancestor whose searchable scope includes this composed edge.
Indexed canonical nodes then support both direct and relationship queries, including
search(Child.class).whereParent(parentId), without requiring DOCUMENT persistence.
An ancestor-ID filter needs no searchable parent; a parent-content predicate requires an indexed parent node.
Identity-based Graph navigation needs neither search documents nor an explicit composition path.
apiDoc() optionally describes the list-valued property created at that path when the graph is used as a
documented web response. It has no effect unless pathInParent() is set.
By default the relationship also owns the child's lifecycle: deleting the referenced parent deletes this model and
its likewise owned descendants in the same atomic model commit. Set deleteOnParentDeletion() to
false for a non-owning relation, including shared or independently retained children.
Disabling cascade does not block deletion of the referenced parent; enforce such restrictions with domain rules.
It also does not permit concrete Graph cycles. This lifecycle rule does not require a graph path and
moving a child by changing its parent ID does not count as parent deletion.
Sole-Graph event/notification handlers for a cascaded child observe its empty current value and historical
before-state through the original published event, just as for a direct logical deletion. Reading that before-state
requires stored history; DOCUMENT-only persistence does not retain previous document versions.
Declaring metadata does not cause a parent to be loaded when the child is loaded or updated.
A one-to-one companion model may annotate the same property with EntityId; entity-ID affixes affect only
the companion's repository identity and do not alter the parent reference value.
- See Also:
-
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionOptional API documentation for the list-valued graph property atpathInParent().booleanWhether this model is deleted when the referenced parent is logically deleted.Optional slash-separated, non-reserved collection path relative to the parent document.booleanWhether search Graphs may include this child and its descendants through this relationship.Class<?>[]Explicit possible parent model types for a polymorphicIdproperty.Class<?> Explicit parent model type for an untyped ID.
-
Element Details
-
value
-
types
Class<?>[] typesExplicit possible parent model types for a polymorphicIdproperty.At runtime the concrete
Idsubtype selects exactly one of these model types through its declared type. This keeps graph validation, API documentation, cascade deletion and cycle detection statically knowable while allowing one domain property such asId<?> nomineeto refer to different model types. This attribute andvalue()are mutually exclusive. The standard serializer preserves polymorphic IDs as an object withname(logical Model name) andid(functional ID). Each allowed Model must declare its concrete ID class asEntityId. This allowlist is also enforced when reading the discriminator; unknown or ambiguous names are rejected.- Default:
{}
-
pathInParent
String pathInParentOptional slash-separated, non-reserved collection path relative to the parent document.- Default:
""
-
searchable
boolean searchableWhether search Graphs may include this child and its descendants through this relationship.Set to
falseto exclude this complete branch from ancestor search documents and Graph-document notifications, in every projection mode. Search activation is not inherited through an excluded edge. The child's ownModel.searchable()choice, other parent edges, ordinary Graph navigation, response composition and deletion policy remain independent. This setting does not activate search by itself and has no effect on schedule ownership.This policy is persisted with the relationship. Existing relationships retain their previous policy until explicitly rewritten; an annotation change or an ordinary value-only update does not rewrite them. Rebuild existing stored Graph projections after migrating the relationships.
- Default:
true
-
apiDoc
ApiDoc apiDocOptional API documentation for the list-valued graph property atpathInParent().The child item schema is inferred from the model that declares this parent reference. Nested path segments are represented as objects, while the final path segment is represented as an array of child models. Structural
ApiDochints such asApiDoc.type(),ApiDoc.format(), andApiDoc.implementation()cannot override that inferred array and child type. UseApiDoc.exclude()to keep this relationship out of every documented graph while retaining it in the runtime model graph.- Default:
@io.fluxzero.sdk.web.ApiDoc
-
deleteOnParentDeletion
boolean deleteOnParentDeletionWhether this model is deleted when the referenced parent is logically deleted.The default expresses parent-owned child lifecycle. Set this to
falsefor a non-owning Graph relation or a model which must remain independently addressable after this parent disappears. The policy is per edge: another owning parent may still cascade deletion to the same child. This setting does not prevent parent deletion or relax Graph cycle checks.- Default:
true
-