JDBC Driver
This page is the JDBC reference. For the higher-level Java SDK overview, see Java SDK.
At a glance
Section titled “At a glance”| Coordinates | ai.particledb:particledb-jdbc:1.0.0 |
| JDBC driver class | org.particledb.Driver |
| URL prefix | jdbc:particledb://host:port/database |
| Default port | 5440 (PDB native wire) — 5443 for TLS |
| Transport | PDB native wire v2 (HTTP/2-style multiplex over one TCP) |
| Dependencies | Netty 4.1.115, Apache Arrow 15.0.2 (optional, required for SELECT) |
| License | Apache-2.0 |
| Min Java | 11 (DDL/DML); 17+ recommended for SELECT |
Install
Section titled “Install”Available on Maven Central — no extra
<repository> declaration needed.
<dependencies> <dependency> <groupId>ai.particledb</groupId> <artifactId>particledb-jdbc</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>org.apache.arrow</groupId> <artifactId>arrow-vector</artifactId> <version>15.0.2</version> </dependency> <dependency> <groupId>org.apache.arrow</groupId> <artifactId>arrow-memory-netty</artifactId> <version>15.0.2</version> </dependency></dependencies>dependencies { implementation("ai.particledb:particledb-jdbc:1.0.0") implementation("org.apache.arrow:arrow-vector:15.0.2") implementation("org.apache.arrow:arrow-memory-netty:15.0.2")}dependencies { implementation 'ai.particledb:particledb-jdbc:1.0.0' implementation 'org.apache.arrow:arrow-vector:15.0.2' implementation 'org.apache.arrow:arrow-memory-netty:15.0.2'}libraryDependencies ++= Seq( "ai.particledb" % "particledb-jdbc" % "1.0.0", "org.apache.arrow" % "arrow-vector" % "15.0.2", "org.apache.arrow" % "arrow-memory-netty" % "15.0.2",)curl -L -o particledb-jdbc-1.0.0.jar \ https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jarcurl -L -o particledb-jdbc-1.0.0-all.jar \ https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0-all.jarJVM flags (required for result-set decode)
Section titled “JVM flags (required for result-set decode)”Arrow Java reflects into ByteBuffer internals; Netty also benefits
from explicit reflection access. Add to your JVM startup arguments — or
set in pom.xml/build.gradle for tests:
--add-opens=java.base/java.nio=ALL-UNNAMED--add-opens=java.base/sun.nio.ch=ALL-UNNAMED-Dio.netty.tryReflectionSetAccessible=trueThe driver throws a clear, actionable error if the add-opens flags
are missing when a SELECT result-set is decoded (it does NOT silently
fall back to raw bytes). The Netty system property is recommended; the
samples module sets it by default.
URL format
Section titled “URL format”jdbc:particledb://host[:port][/database][?option=value&...]User + password are passed as separate JDBC Properties (or via the
PdbDataSource setters), not embedded in the URL. The parser does not
support user:password@ userinfo today.
Connection options
Section titled “Connection options”| Option | Default | Description |
|---|---|---|
prepareThreshold | 5 | Number of executions before promotion to a server-side prepared statement. Matches pgjdbc. |
preparedStatementCacheQueries | 256 | Client-side prepared statement cache size (entries). |
preparedStatementCacheSizeMiB | 5 | Client-side prepared statement cache cap (MiB). |
maxStreamsPerConn | 64 | Wire-v2 multiplex stream cap per TCP connection. |
preferUnixSocket | true | Try /tmp/.s.PDB.<port> first when host is local. |
connectTimeout | 30000 | TCP + handshake timeout, milliseconds. |
sslMode | disable | TLS mode (see below). |
sslRootCert | — | Path to PEM CA bundle for verify-ca / verify-full. |
sslCert | — | Path to PEM client cert for mTLS. |
sslKey | — | Path to PEM client private key for mTLS. |
TLS modes (pgjdbc-compatible)
Section titled “TLS modes (pgjdbc-compatible)”| Mode | Encrypts wire? | Verifies CA chain? | Verifies hostname? |
|---|---|---|---|
disable | no | no | no |
require | yes | no | no |
verify-ca | yes | yes | no |
verify-full | yes | yes | yes |
Use verify-full in production. The TLS port is 5443; port 5440 is
plaintext PDB wire.
Hello world
Section titled “Hello world”import java.sql.*;
public class Hello { public static void main(String[] args) throws Exception { Class.forName("org.particledb.Driver"); try (Connection c = DriverManager.getConnection( "jdbc:particledb://127.0.0.1:5440/default"); Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT 1")) { while (rs.next()) System.out.println(rs.getInt(1)); } }}DataSource
Section titled “DataSource”import org.particledb.ds.PdbDataSource;
PdbDataSource ds = new PdbDataSource();ds.setHost("db.internal.example.com");ds.setPort(5443);ds.setDatabase("postgres");ds.setUser("app");ds.setPassword(System.getenv("PDB_PASSWORD"));ds.setSslMode("verify-full");ds.setSslRootCert("/etc/ssl/internal-ca.crt");
try (Connection c = ds.getConnection()) { // ...}PdbDataSource exposes Hikari-friendly bean setters for every option in
the table above.
Connection pooling
Section titled “Connection pooling”The driver does not ship a built-in pool. Use HikariCP:
HikariConfig cfg = new HikariConfig();cfg.setJdbcUrl("jdbc:particledb://127.0.0.1:5440/default");cfg.setMaximumPoolSize(10);cfg.setMinimumIdle(1);cfg.setConnectionTimeout(30_000);cfg.setPoolName("pdb-app");
HikariDataSource ds = new HikariDataSource(cfg);PDB wire v2 already multiplexes streams per TCP connection, so a small pool (≤10) is typically sufficient.
Transactions
Section titled “Transactions”PDB native wire treats BEGIN/COMMIT/ROLLBACK as batch markers, not
full ACID transaction brackets. This means:
Connection.setAutoCommit(false)+ a series of writes +commit()works correctly — writes flush as a batch oncommit().Connection.rollback()after a flushed write does not undo it on PDB native wire.SAVEPOINTand isolation-level pinning are not yet supported on PDB native wire.
If your app relies on rollback-after-write or savepoints, connect via the PostgreSQL wire (port 5432) using stock pgjdbc instead — see the PG wire page. That path supports the full pgjdbc feature set including server-side prepared statements, pipelined execution, and interactive transactions.
Runnable samples
Section titled “Runnable samples”Each sample is a main class under
sdk/java/jdbc/samples/:
| Sample | Demonstrates |
|---|---|
HelloWorld | Smallest round-trip: SELECT 1. |
CrudRoundtrip | CREATE / INSERT / SELECT / UPDATE / DELETE. |
TransactionDemo | setAutoCommit(false) + RYOW within a batch. |
HikariCpDemo | HikariCP integration. |
PgJdbcCompat | PG-wire compatibility via stock pgjdbc. |
Run any sample after booting a local ParticleDB:
particledb start --no-auth --txn-mode occ-v3 \ --pg-addr 127.0.0.1:5432 --pdb-port 5440
cd sdk/java/jdbc/samplesmvn exec:exec -Dexec.mainClass=ai.particledb.jdbc.samples.HelloWorldVerifying downloaded artifacts
Section titled “Verifying downloaded artifacts”Checksums and GPG signatures are published next to the JAR under the standard Maven Central layout:
https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jar.md5https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jar.sha1https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jar.asccurl -L -o /tmp/particledb-jdbc-1.0.0.jar \ https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jarEXPECTED=$(curl -sL https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jar.sha1)ACTUAL=$(shasum -a 1 /tmp/particledb-jdbc-1.0.0.jar | awk '{print $1}')[ "$EXPECTED" = "$ACTUAL" ] && echo OK || echo MISMATCHArchitecture
Section titled “Architecture”| Class | Purpose |
|---|---|
org.particledb.Driver | JDBC Driver. SPI-registered via META-INF/services/java.sql.Driver. |
org.particledb.PdbConnection | JDBC Connection. Wraps a StreamMux so each statement runs on its own multiplexed stream. |
org.particledb.PdbPreparedStatement | JDBC PreparedStatement with client-side parameter substitution and prepared-cache analytics. |
org.particledb.PdbResultSet | JDBC ResultSet. Decodes Arrow IPC via the optional arrow-vector dependency. |
org.particledb.wire.WireV2Codec | Netty ByteToMessageDecoder for v1 (8-byte header) and v2 (11-byte header) frames. |
org.particledb.wire.StreamMux | Multiplexed connection manager: one TCP socket, N concurrent streams. |
org.particledb.wire.ConnPool | Small pool of mux instances for high-fan-out scenarios. |
org.particledb.ds.PdbDataSource | javax.sql.DataSource impl with HikariCP-friendly bean setters. |
Wire negotiation
Section titled “Wire negotiation”The driver always starts in v1 framing, sends a v1-framed HELLO
announcing both CAP_V1_LEGACY and CAP_V2_MUX, and the server picks:
- v1 server: returns
chosen_caps & 0x02 == 0. Driver stays in v1 single-stream mode (one outstanding request at a time). - v2 server: returns
chosen_caps & 0x02 == 1. Driver switches to v2 framing (11-byte header) and opens up tomaxStreamsPerConnin-flight streams on this TCP connection.
See PDB_WIRE_V2 architecture for the full v2 spec.
Source + further reading
Section titled “Source + further reading”- Driver:
sdk/java/jdbc/ - Samples:
sdk/java/jdbc/samples/ - Changelog:
sdk/java/jdbc/CHANGELOG.md - Release runbook:
docs/release/JAVA_SDK_MAVEN_RELEASE.md
Roadmap (v1.1)
Section titled “Roadmap (v1.1)”- TLS
sslMode=require/verify-ca/verify-full(handshake currently validated on the connect path; per-mode strictness landing in v1.1). - Server-side Parse/Bind/Execute split (once the v2 server exposes those opcodes).
- Full Arrow IPC decoding without reflection.
- JNDI registration for app-server deployments.
CallableStatementfor stored procedures.