# 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();
```