166 lines
5.0 KiB
Markdown
166 lines
5.0 KiB
Markdown
# 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
|
|
<dependency>
|
|
<groupId>com.binarygolem.clotho</groupId>
|
|
<artifactId>clotho-spring-boot-starter</artifactId>
|
|
<version>${clotho.version}</version>
|
|
</dependency>
|
|
```
|
|
|
|
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<Employee> findByDepartment(@Param("dept") String dept);
|
|
}
|
|
```
|
|
|
|
```java
|
|
@Service
|
|
public class EmployeeService {
|
|
|
|
@Autowired EmployeeQueries employeeQueries; // injected by Spring
|
|
|
|
public List<Employee> 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();
|
|
```
|