# Spring Integration ## Overview The `clotho-spring-boot-starter` module provides: - Autoconfiguration of `ClothoSessionFactory` as a singleton Spring bean - Session scoping tied to the Spring `@Transactional` lifecycle - Classpath scanning for `@ClothoRepository` interfaces and automatic proxy bean registration - `application.properties` / `application.yml` configuration support The core `clotho-core` module has zero Spring dependency. Everything Spring-specific lives in `clotho-spring-boot-starter`. --- ## Adding the Starter ```xml com.binarygolem.clotho clotho-spring-boot-starter ${clotho.version} ``` No additional `@EnableXxx` annotation is required. The autoconfiguration activates automatically when the starter is on the classpath and `clotho.gremlin.url` is configured. --- ## `application.properties` Reference | Key | Default | Description | |---|---|---| | `clotho.gremlin.url` | (required) | WebSocket URL for ArcadeDB Gremlin endpoint | | `clotho.gremlin.username` | `""` | ArcadeDB username | | `clotho.gremlin.password` | `""` | ArcadeDB password | | `clotho.gremlin.traversal-source` | `g` | Name of the traversal source on the server | | `clotho.default-direction` | `OUT` | Default edge direction for `@Via` fields | | `clotho.unknown-type-behavior` | `STRICT` | `STRICT`, `NEAREST_ANCESTOR`, or `GENERIC` | | `clotho.packages` | (required) | Comma-separated packages to scan for `@VertexType` / `@EdgeType` / `@ClothoRepository` | **Example:** ```properties clotho.gremlin.url=ws://localhost:8182/gremlin clotho.gremlin.username=root clotho.gremlin.password=playwithdata clotho.gremlin.traversal-source=g clotho.default-direction=OUT clotho.unknown-type-behavior=STRICT clotho.packages=com.example.myapp.domain,com.example.myapp.repository ``` --- ## Beans Provided by Autoconfiguration | Bean | Type | Description | |---|---|---| | `clothoSessionFactory` | `ClothoSessionFactory` | Singleton; holds connection and TypeRegistry | | `clothoTransactionManager` | `PlatformTransactionManager` | Bridges Spring `@Transactional` to Clotho sessions | Repository beans (one per `@ClothoRepository` interface found during scan) are also registered automatically. --- ## Transaction Integration Clotho integrates with Spring's `@Transactional` annotation via a `PlatformTransactionManager` implementation. A `ClothoSession` is opened when a transaction begins and closed (or rolled back) when the transaction ends. ```java @Service public class OrderService { @Autowired ClothoSessionFactory sessionFactory; @Autowired OrderQueries orderQueries; @Transactional public void fulfillOrder(ARID orderId) { ClothoSession session = sessionFactory.currentSession(); Order order = session.load(Order.class, orderId); order.setStatus("FULFILLED"); session.save(order); // session.save() is called; commit happens when @Transactional method returns } } ``` ### Session Scope Within a `@Transactional` method, `sessionFactory.currentSession()` always returns the same `ClothoSession`. The identity map is scoped to this session — the same ARID loaded twice returns the same Java instance. Outside a transaction, each `sessionFactory.openSession()` call creates a new session. The caller is responsible for closing it: ```java try (ClothoSession session = sessionFactory.openSession()) { Employee emp = session.load(Employee.class, rid); // ... } ``` ### Transaction Semantics **Note**: ArcadeDB's Gremlin Server transaction behavior needs verification. Gremlin typically treats each request as an auto-committed transaction. For multi-step operations (e.g., creating a vertex and then an edge), the behavior depends on the server configuration. This will be refined once verified against the live ArcadeDB instance. --- ## `@ClothoRepository` Injection ```java @ClothoRepository public interface EmployeeQueries { @Query("g.V().hasLabel('Employee').has('dept',:dept)") List findByDepartment(@Param("dept") String dept); } ``` ```java @Service public class EmployeeService { @Autowired EmployeeQueries employeeQueries; // injected by Spring public List getEngineers() { return employeeQueries.findByDepartment("Engineering"); } } ``` The proxy generated for `EmployeeQueries` uses the `ClothoSession` from the current transaction context (or opens a new one for the call duration if no transaction is active). --- ## Manually Constructing `ClothoSessionFactory` (without Spring) ```java ClothoSessionFactory factory = ClothoSessionFactory.builder() .url("ws://localhost:8182/gremlin") .credentials("root", "playwithdata") .traversalSource("g") .defaultDirection(Direction.OUT) .unknownTypeBehavior(UnknownTypeBehavior.STRICT) .scanPackages("com.example.domain") .build(); try (ClothoSession session = factory.openSession()) { Employee emp = session.load(Employee.class, ARID.of("#10:0")); emp.setName("Updated"); session.save(emp); } factory.close(); ```