Java Embedded
Run Traverse as an in-process graph database in Java applications.
Install
Maven
<dependency>
<groupId>com.truespar</groupId>
<artifactId>traverse-java</artifactId>
<version>0.6.2</version>
</dependency>
Note: The native library is bundled inside the JAR and extracted automatically at runtime. No separate native install is needed. Requires Java 25+.
Open a Database
import com.truespar.traverse.Database;
import com.truespar.traverse.Transaction;
import com.truespar.traverse.BulkWriter;
import com.truespar.traverse.QueryResult;
// Open or create a database
try (Database db = Database.open("mydb.tvdb")) {
// use db
}
// Open with a license key
try (Database db = Database.openLicensed("mydb.tvdb", "tskey_...")) {
// use db
}
Run Queries
try (Database db = Database.open("mydb.tvdb")) {
try (Transaction tx = db.begin()) {
QueryResult result = tx.execute(
"MATCH (n:Person) RETURN n.name, n.age"
);
for (var row : result) {
System.out.println(row.get("n.name"));
System.out.println(row.get("n.age"));
}
tx.abort();
}
}
Query Parameters
try (Transaction tx = db.begin()) {
QueryResult result = tx.execute(
"MATCH (n:Person) WHERE n.age > $minAge RETURN n.name",
Map.of("minAge", 25)
);
tx.abort();
}
Write Data
try (Transaction tx = db.begin()) {
tx.execute("CREATE (p:Person {name: 'Alice', age: 30})");
tx.execute("CREATE (p:Person {name: 'Bob', age: 25})");
tx.commit();
}
Note: If close() is called without a prior commit(), the transaction is automatically aborted. Use try-with-resources for safe cleanup.
Transactions
try (Transaction tx = db.begin()) {
tx.execute("CREATE (p:Person {name: 'Carol'})");
tx.execute(
"MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Carol'}) " +
"CREATE (a)-[:KNOWS]->(b)"
);
tx.commit();
}
// If an exception is thrown, close() auto-aborts the transaction
Bulk Writer
The BulkWriter bypasses MVCC for high-throughput imports (2–5M rows/s).
try (BulkWriter writer = db.bulkWriter()) {
long nid1 = writer.createNode(
new String[]{"Person"},
Map.of("name", "Alice", "age", 30)
);
long nid2 = writer.createNode(
new String[]{"Person"},
Map.of("name", "Bob", "age", 25)
);
writer.createEdge(nid1, nid2, "KNOWS", Map.of("since", 2024));
writer.commit();
}
Nodes can be created with labels only:
long nid = writer.createNode(new String[]{"Company", "Active"});
Edges can be created without properties:
writer.createEdge(sourceId, targetId, "WORKS_AT");
Indexes
Create indexes via the bulk writer or Cypher:
// Via BulkWriter
try (BulkWriter writer = db.bulkWriter()) {
writer.createIndex("idx_person_name", "Person", "name");
writer.createEdgeIndex("idx_knows_since", "KNOWS", "since");
writer.createEdgeIndex("idx_knows", "KNOWS"); // type-only index
writer.commit();
}
// Via Cypher
try (Transaction tx = db.begin()) {
tx.execute("CREATE INDEX idx_person_age FOR (n:Person) ON (n.age)");
tx.commit();
}
Drop an edge index:
try (BulkWriter writer = db.bulkWriter()) {
writer.dropEdgeIndex("idx_knows_since");
writer.commit();
}
Flush and Close
// Flush dirty pages to disk
db.flush();
// Close the database (also called automatically by try-with-resources)
db.close();
Note: Traverse is an in-memory database. Call flush() to persist data to the .tvdb file. Data written since the last flush is lost if the process crashes.