# Object Boundary ## What Is the Object Boundary? Clotho has no lazy loading. When you call `session.load(Employee.class, rid)`, you receive the fully assembled object — root vertex plus everything within its declared boundary — in one operation. Nothing is deferred. The **object boundary** is the set of edges and vertices Clotho traverses and assembles when loading a `@VertexType` instance. It is declared entirely in the Java class using `@Include` and `@Via`. Everything outside the boundary is accessed via `@Query` traversals written by the developer. --- ## Declaring the Boundary: `@Include` and `@Via` ```java @VertexType("Order") public class Order extends ClothoVertex { String status; @Include @Via("HAS_LINE") List lines; @Include @Via("HAS_BILLING_ADDRESS") Address billingAddress; } ``` - `@Include` marks the field as part of this object's boundary. - `@Via` specifies the ArcadeDB edge label to traverse. - The field type determines what is loaded (see below). Both annotations are required together. `@Include` without `@Via` is a compile-time error. --- ## What Gets Loaded: Field Type Rules ### Field type is a `@VertexType` class Clotho traverses the edge, loads the target vertex (and its own boundary recursively), and discards the edge itself (edge properties are not available). ```java @Include @Via("HAS_BILLING_ADDRESS") Address billingAddress; // Address is a @VertexType; edge properties ignored ``` ### Field type is an `@EdgeType` class Clotho loads the full edge object — edge properties, plus `@OutVertex` and `@InVertex` fields if declared on the edge class. ```java @Include @Via("HAS_LINE") List lines; // OrderLineEdge is an @EdgeType; edge props + vertices loaded ``` ### Edge-only inclusion (no `@InVertex` on the edge class) When the `@EdgeType` class declares no `@InVertex` field, the target vertex is not fetched. Useful when you need the edge's own properties but not the vertex it points to. ```java @EdgeType("TAGGED_WITH") public class TagEdge extends ClothoEdge { @OutVertex Order order; // No @InVertex — Tag vertex is never loaded String tagValue; int weight; } // In Order: @Include @Via("TAGGED_WITH") List tags; // Only edge properties; Tag vertices stay in the DB ``` --- ## Edge Direction Default direction is `OUT` (follow outgoing edges from the current vertex). Override per field with `@Direction`: ```java @Include @Via("ASSIGNED_TO") @Direction(Direction.IN) List assignedTasks; // follow INCOMING ASSIGNED_TO edges to find tasks @Include @Via("CONNECTED") @Direction(Direction.BOTH) List neighbors; // follow edges in both directions ``` The global default can be changed in session factory configuration: ```properties clotho.default-direction=OUT ``` --- ## Multi-Hop Boundaries `@Include` is applied recursively. If `OrderLine` itself has `@Include` fields, they are loaded as part of loading `Order`. ```java @VertexType("Order") public class Order extends ClothoVertex { @Include @Via("HAS_LINE") List lines; // hop 1 } @VertexType("OrderLine") public class OrderLine extends ClothoVertex { int quantity; BigDecimal unitPrice; @Include @Via("HAS_NOTE") List notes; // hop 2 — loaded as part of Order } ``` Loading an `Order` traverses: `Order → HAS_LINE → OrderLine → HAS_NOTE → Note`. There is no depth limit. The developer is responsible for designing boundaries that do not load unbounded portions of the graph. --- ## Cycle Detection Clotho tracks visited ARIDs during a boundary load. If a traversal reaches a vertex it has already loaded in the current operation, it uses the existing instance and stops traversing further — it does not loop. The developer still bears responsibility for not creating boundaries that load huge subgraphs. --- ## Persistence of Boundary Elements When `session.save(order)` is called: 1. The root `Order` vertex is upserted (created if ARID is null, updated if set). 2. Each `@Include` field is recursively persisted in the same way. 3. Elements reachable via multiple paths are saved exactly once (identity map deduplication). 4. **Removed items are NOT automatically deleted.** If you remove an `OrderLine` from `order.lines`, calling `save()` does not delete the `OrderLine` vertex or its edges. Call `session.delete(orderLine)` explicitly. --- ## Design Guidance The boundary should reflect **ownership**, not just connectivity. Include elements that: - Are always loaded and managed together with the root - Are not meaningful without the root (e.g., `OrderLine` without `Order`) - Form a bounded transaction unit Do NOT include: - Large, unbounded collections (e.g., all products a customer ever bought) - Elements that are independently meaningful and queried on their own - Elements reachable via long traversal chains across the domain For everything outside the boundary, write a `@Query` on a `@ClothoRepository` interface.