# Annotation Reference ## Class-Level Annotations --- ### `@VertexType` Declares a class as a Clotho-managed vertex type. The class must extend `ClothoVertex`. ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface VertexType { String value(); // ArcadeDB vertex type name (required) String[] additionalParents() // ArcadeDB parent type names beyond Java hierarchy default {}; // Use for diamond inheritance String parentLabel() // Explicit ArcadeDB parent when Java hierarchy diverges default ""; } ``` **Examples:** ```java // Simple @VertexType("Employee") public class Employee extends ClothoVertex { } // Abstract type @VertexType("Person") public abstract class Person extends ClothoVertex { } // Diamond inheritance @VertexType(value = "ContractEmployee", additionalParents = {"Contractor"}) public class ContractEmployee extends Employee { } // Divergent Java/ArcadeDB hierarchy @VertexType(value = "ExternalWorker", parentLabel = "Employee") public class ExternalWorker extends ClothoVertex { } ``` --- ### `@EdgeType` Declares a class as a Clotho-managed edge type. The class must extend `ClothoEdge`. ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface EdgeType { String value(); // ArcadeDB edge type name (required) } ``` **Example:** ```java @EdgeType("WORKS_AT") public class WorksAt extends ClothoEdge { public static final String LABEL = "WORKS_AT"; // ... } ``` Convention: define `LABEL` as a constant on the edge class to avoid magic strings at call sites when referencing the label in `@Via`. --- ### `@SubgraphType` Declares a composite type assembled from a Gremlin `select()` traversal. Must NOT extend `ClothoVertex` or `ClothoEdge`. Has no ARID. ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface SubgraphType { } ``` **Example:** ```java @SubgraphType public class EmployeeProfile { Employee employee; Manager manager; @Alias("dept") Department department; List workHistory; } ``` --- ## Field-Level Annotations --- ### `@RID` Marks the field that holds the element's `ARID`. Inherited from `ClothoEntity`; generally not needed unless overriding the base class field. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface RID { } ``` --- ### `@Property` Maps a field to an ArcadeDB vertex or edge property. Optional when the field name exactly matches the property name. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Property { String value(); // ArcadeDB property name } ``` **Example:** ```java @Property("startDate") LocalDate start; // field name differs from property name LocalDate endDate; // no annotation needed; names match ``` --- ### `@Include` Marks a field as part of this object's eager-load boundary. Always paired with `@Via`. The field type must be a `@VertexType` class, an `@EdgeType` class, or a `List<>` of either. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Include { } ``` --- ### `@Via` Specifies the ArcadeDB edge label to traverse for an `@Include` field. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Via { String value(); // Edge label (required) } ``` **Strongly preferred pattern** — use the edge class's `LABEL` constant: ```java @Include @Via(WorksAt.LABEL) List workHistory; ``` --- ### `@Direction` Specifies which edge direction to follow for an `@Include` + `@Via` traversal. Defaults to `OUT` (or the global configured default). ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Direction { Direction value() default Direction.OUT; } public enum Direction { OUT, IN, BOTH } ``` **Example:** ```java @Include @Via("ASSIGNED_TO") @Direction(Direction.IN) List assignedTasks; ``` --- ### `@OutVertex` On an `@EdgeType` class: marks the field holding the out-vertex (source) of the edge. The field type must be a `@VertexType` class. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface OutVertex { } ``` --- ### `@InVertex` On an `@EdgeType` class: marks the field holding the in-vertex (target) of the edge. The field type must be a `@VertexType` class. Omitting `@InVertex` entirely = edge-only inclusion; the target vertex is not loaded. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface InVertex { } ``` --- ### `@Alias` On a `@SubgraphType` field: specifies the Gremlin `as()` alias that this field is bound to. Defaults to the field name when omitted. ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Alias { String value(); } ``` **Example:** ```java @Alias("dept") Department department; // binds to .as("dept") in the Gremlin query ``` --- ## Query Annotations --- ### `@Query` Declares a Gremlin traversal. Used on `@ClothoRepository` interface methods (primary use) or on `@VertexType` classes as named queries (secondary use). ```java @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Queries.class) // allows multiple @Query on a class (different names) public @interface Query { String value() default ""; // Gremlin string (for method use) String name() default ""; // Named query identifier (for class-level use) String gremlin() default ""; // Gremlin string (for class-level use; alias for clarity) boolean mapResult() default true; // false = return raw Gremlin result } ``` **Examples:** ```java // On a repository method @Query("g.V().hasLabel('Employee').has('dept',:dept)") List findByDepartment(@Param("dept") String dept); // Raw result — no Clotho mapping @Query(value = "g.V().hasLabel('Employee').count()", mapResult = false) long countAll(); // Named query on a class @VertexType("Order") @Query(name = "openForCustomer", gremlin = "g.V().has('Customer','id',:custId).out('PLACED').has('status','OPEN')") public class Order extends ClothoVertex { ... } ``` --- ### `@Param` Binds a method parameter to a named placeholder in a `@Query` Gremlin string. ```java @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Param { String value(); // placeholder name (without the colon) } ``` **Example:** ```java @Query("g.V().has('Employee','dept',:dept).has('level',:level)") List findByDeptAndLevel( @Param("dept") String department, @Param("level") int level); ``` --- ## Spring Annotation --- ### `@ClothoRepository` Marks an interface as a Clotho query interface. The `clotho-spring-boot-starter` scans for these interfaces and registers a dynamic proxy as a Spring bean. ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ClothoRepository { } ``` **Example:** ```java @ClothoRepository public interface OrderQueries { @Query("g.V().has('Order','status','OPEN')") List findOpenOrders(); } ``` Inject via Spring as you would any repository: ```java @Autowired OrderQueries orderQueries; ```