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.