Skip to content

Releases: neo4j/neo4j-jdbc

6.7.3

28 Jul 10:10
Compare
Choose a tag to compare

What's Changed

🐛 Bug Fixes

  • 12e2b86 fix: Proper test multiple node types, and fix metadata doc.

🧹 Housekeeping

  • 225cfdf Bump com.opencsv:opencsv from 5.11.2 to 5.12.0 (#1053)
  • 04901e3 Bump spring-boot.version from 3.5.3 to 3.5.4 (#1056)
  • c9036b2 Bump org.junit:junit-bom from 5.13.3 to 5.13.4 (#1055)
  • 56c0fb9 Bump org.hibernate.orm:hibernate-platform (#1054)
  • 7ff8dd9 Bump quarkus.platform.version from 3.24.4 to 3.24.5 (#1052)

6.7.2

21 Jul 09:09
Compare
Choose a tag to compare

What's Changed

🚀 Features

  • f8078f1 feat: Allow to configure User-Agent from a dedicated resource. (#1041)

🐛 Bug Fixes

  • 259f89a fix: Prevent a class cast exception when transmitting parameters of type Point or IsoDuration to the server. (#1042)

🧹 Housekeeping

  • aca6fda Bump io.netty:netty-bom from 4.1.121.Final to 4.1.123.Final (#1049)
  • dbfc88a Bump quarkus.platform.version from 3.24.3 to 3.24.4 (#1048)
  • 392a48e Bump org.graalvm.buildtools:native-maven-plugin (#1047)
  • 4843e90 Bump org.moditect:moditect-maven-plugin (#1046)
  • fb9d651 Bump org.apache.maven.plugins:maven-enforcer-plugin (#1045)
  • df64186 Bump com.fasterxml.jackson:jackson-bom (#1044)

🛠 Build

  • 5c9984f build: Remove workarounds for JUnit 5.13 to work with older native image build tools. (#1050)

6.7.1

14 Jul 14:06
Compare
Choose a tag to compare

What's Changed

🚀 Features

  • dad6a0d feat: Allow user-agent customisation via env-variables or system properties. (#1032)

📝 Documentation

  • 864b042 docs: Update local changelog.
  • 72102a5 docs: Remove quotes from prerelease attribute. (#1033)

🧹 Housekeeping

  • 0404c49 Bump io.micrometer:micrometer-bom from 1.15.1 to 1.15.2 (#1039)
  • e0b401d Bump quarkus.platform.version from 3.24.2 to 3.24.3 (#1037)
  • 6e75f97 Bump org.hibernate.orm:hibernate-platform (#1038)
  • 0d0ec22 Bump mybatis-spring-boot-starter.version (#1036)
  • 9217bf1 Bump org.neo4j:cypher-v5-antlr-parser from 5.26.8 to 5.26.9 (#1035)
  • ac484d1 Bump io.micrometer:micrometer-tracing-bom (#1034)

🛠 Build

  • cdc7a19 test: Add integration tests for retrieving the user-agent. (#1040)
  • b7f4f90 build: Upgrade stubserver / testkit tests to use latest Python 3.10 image.

6.7.0

09 Jul 12:16
Compare
Choose a tag to compare

What's Changed

Can your JDBC driver do this?

To highlight some of the features that have accumulated in the Neo4j JDBC driver since the first commit to the 6.x branch two years ago, we decided to create two hopefully easy to read demos before we jump into the list of features. We use plain Java in the first 3 examples, no dependency management and run fully on the module path with Demo1.java. The keen reader may notices that we do use some Java 24 preview features: Why bother with a class definition? And if we have Java modules, why not use them for import statements? (Be aware, that the JDBC driver does run on Java 17, too and does not require any preview feature)

Cypher and SQL supported

First, let's download the JDBC bundle:

wget https://repo.maven.apache.org/maven2/org/neo4j/neo4j-jdbc-full-bundle/6.7.0/neo4j-jdbc-full-bundle-6.7.0.jar

And run the following class

import module java.sql;

void main() throws SQLException {

    try (
        var connection = DriverManager.getConnection("jdbc:neo4j://localhost:7687/movies", "neo4j", "verysecret");
        var stmt = connection.prepareStatement("""
            MERGE (g:Genre {name: $1})
            MERGE (m:Movie {title: $2, released: $3}) -[:HAS]->(g)
            FINISH"""))
    {
        stmt.setString(1, "Science Fiction");
        stmt.setString(2, "Dune");
        stmt.setInt(3, 2021);
        stmt.addBatch();

        stmt.setString(1, "Science Fiction");
        stmt.setString(2, "Star Trek Generations");
        stmt.setInt(3, 1994);
        stmt.addBatch();

        stmt.setString(1, "Horror");
        stmt.setString(2, "Seven");
        stmt.setInt(3, 1995);
        stmt.addBatch();

        stmt.executeBatch();
    }

    // Not happy with Cypher? Enable SQL translations
    try (
        var connection = DriverManager.getConnection("jdbc:neo4j://localhost:7687/movies?enableSQLTranslation=true", "neo4j", "verysecret");
        var stmt = connection.createStatement();
        var rs = stmt.executeQuery("""
            SELECT m.*, collect(g.name) AS genres
            FROM Movie m NATURAL JOIN HAS r NATURAL JOIN Genre g
            WHERE m.title LIKE 'S%'    
            ORDER BY m.title LIMIT 20"""))
    {
        while (rs.next()) {
            var title = rs.getString("title");
            var genres = rs.getObject("genres", List.class);
            System.out.println(title + " " + genres);
        }
    }
}

like this:

java --enable-preview --module-path neo4j-jdbc-full-bundle-6.7.0.jar Demo1.java

The output of the program will be similar to this. Notice how the Cypher has been rewritten to be proper batched:

Juli 09, 2025 12:52:54 PM org.neo4j.jdbc.PreparedStatementImpl executeBatch
INFORMATION: Rewrite batch statements is in effect, statement MERGE (g:Genre {name: $1})
MERGE (m:Movie {title: $2, released: $3}) -[:HAS]->(g)
FINISH has been rewritten into UNWIND $__parameters AS __parameter MERGE (g:Genre {name: __parameter['1']})
MERGE (m:Movie {title: __parameter['2'], released: __parameter['3']}) -[:HAS]->(g)
FINISH
Seven [Horror]
Star Trek Generations [Science Fiction]
Horror
Science Fiction

Bonus example As JDBC 4.3, section 13.2 specifies that only ? are allowed as positional parameters, we do of course handle those. The above example uses named Cypher parameters $1, $2 to align them with the indexes that the PreparedStatement requires. If we would switch languages here, using SQL for inserting and Cypher for querying, you see the difference. Also take now that you can unwrap the PreparedStatement into a Neo4jPreparedStatement that allows you to use named parameters proper:

import module java.sql;
import module org.neo4j.jdbc;

void main() throws SQLException {

    try (
        var connection = DriverManager.getConnection("jdbc:neo4j://localhost:7687/movies?enableSQLTranslation=true", "neo4j", "verysecret");
        var stmt = connection.prepareStatement("""
            INSERT INTO Movie (title, released) VALUES (?, ?) 
            ON CONFLICT DO NOTHING
            """))
    {
        stmt.setString(1, "Dune: Part Two");
        stmt.setInt(2, 2024);
        stmt.addBatch();

        stmt.executeBatch();
    }

    try (
        var connection = DriverManager.getConnection("jdbc:neo4j://localhost:7687/movies", "neo4j", "verysecret");
        var stmt = connection.prepareStatement("""
            MATCH (n:$($label)) 
            WHERE n.released = $year 
            RETURN DISTINCT n.title AS title""")
            .unwrap(Neo4jPreparedStatement.class))
    {
        stmt.setString("label", "Movie");
        stmt.setInt("year", 2024);

        var rs = stmt.executeQuery();
        while (rs.next()) {
            var title = rs.getString("title");
            System.out.println(title);
        }
    }
}

As we importing the whole Neo4j JDBC Driver module at the top of the class, we must explicitly add it to the module path. Run the program as follows, so that you don't have to define a module-info.java for that anonymous class:

java --enable-preview --module-path neo4j-jdbc-full-bundle-6.7.0.jar --add-modules org.neo4j.jdbc Demo5.java

Cypher backed views

Your ETL tool just let you run plain selects but you do want to have some more complex Cypher? Don't worry, defined a Cypher-backed view like in demo 2 and we got you covered:

import module java.sql;

void main() throws SQLException, IOException {

    // We do write this definition from the demo to a file, in reality it can be a 
    // module- or classpath resource, a file or a resource on a webserver.
    var viewDefinition = """
        [
          {
            "name": "movies",
            "query": "MATCH (m:Movie)-[:HAS]->(g:Genre) RETURN m, collect(g.name) AS genres",
            "columns": [
              {
                "name": "title",
                "propertyName": "m.title",
                "type": "STRING"
              },
              {
                "name": "genres",
                "type": "ANY"
              }
            ]
          }
        ]""";
    var views = Files.createTempFile("views", ".json");
    Files.writeString(views, viewDefinition);

    var url = "jdbc:neo4j://localhost:7687/movies?enableSQLTranslation=%s&viewDefinitions=%s"
        .formatted(true, "file://" + views.toAbsolutePath());
    try (
        var connection = DriverManager.getConnection(url, "neo4j", "verysecret");
        var stmt = connection.createStatement();
        var rs = stmt.executeQuery("SELECT * FROM movies"))
    {
        while (rs.next()) {
            var title = rs.getString("title");
            var genres = rs.getObject("genres", List.class);
            System.out.println(title + " " + genres);
        }
    }
}

Running

java --enable-preview --module-path neo4j-jdbc-full-bundle-6.7.0.jar Demo2.java

gives you

Dune [Science Fiction]
Star Trek Generations [Science Fiction]
Seven [Horror]

Support for the Neo4j HTTP Query API

Communication with Neo4j is usually done via the Bolt protocol, which is a binary format, running on a dedicated port. That can be problematic at times. Latest Neo4j server 2025.06 and higher have enabled the Query API, that allows Cypher over HTTP. The Neo4j JDBC driver can utilise that protocol, too, by just changing the URL like this:

import module java.sql;

void main() throws SQLException {

    // Can't use Neo4j binary protocol, let's use http…
    var url = "jdbc:neo4j:http://localhost:7474/movies?enableSQLTranslation=true";
    try (
        var connection = DriverManager.getConnection(url, "neo4j", "verysecret");
        var stmt = connection.createStatement();
        var rs = stmt.executeQuery("SELECT * FROM Genre ORDER BY name"))
    {
        while (rs.next()) {
            var genre = rs.getString("name");
            System.out.println(genre);
        }
    }

    // This issue will be fixed in one of the next patch releases
    System.exit(0);
}

Everything else stays the same, the output of the query is

Horror
Science Fiction

Retrieving Graph data as JSON objects

Last but not least, we did add some Object mapping to the driver. This is the only feature that requires an additional dependency. As we decided to go with an intermediate format, JSON, we are using Jackson Databind. With Jackson on the path, you can turn any Neo4j result into JSON by just asking the ResultSet for a JsonNode. The latter can than be converted to any Pojo or collection you desire.

You need JBang to run the last demo. It does the dependency management for us when you run jbang Demo4.java

///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 24
//PREVIEW
//DEPS org.neo4j:neo4j-jdbc:6.7.0
//DEPS com.fasterxml.jackson.core:jackson-databind:2.19.1

import java.sql.DriverManager;
import java.sql.SQLException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

void main() throws SQLException, JsonProcessingException {

    var objectMapper = new ObjectMapper();

    record Movie(String title, int released, List<String> genres) {
    }

    try (
        var connection = DriverManager.getConnection("jdbc:neo4j://localhost:7687/movies", "neo4j", "verysecret");
        var stmt = connection.createStatement();
        var rs = stmt.executeQuery("""
            MATCH (m:Movie)-[:HAS]->(g:Genre)
            WITH m, collect(g.name) AS genres
            RETURN m{.*, genres: genres}
        ...
Read more

6.6.1

01 Jul 16:53
Compare
Choose a tag to compare

What's Changed

🐛 Bug Fixes

  • 99e02e5 fix: Allow coercion of map, list and points to string. (#1021)

🧹 Housekeeping

  • 4e2a668 Bump org.openapitools:openapi-generator-maven-plugin (#1020)
  • 2120b6d Bump com.puppycrawl.tools:checkstyle (#1019)
  • 176f83d Bump org.testcontainers:testcontainers-bom (#1018)
  • cee342a Bump org.hibernate.orm:hibernate-platform (#1017)
  • 1b611d6 Bump org.jetbrains.kotlin:kotlin-stdlib-jdk8 (#1016)
  • cca2982 Bump quarkus.platform.version from 3.23.4 to 3.24.1 (#1015)
  • ecd7c97 build: Bump number of retries for state transition during release by a magnitude.

6.6.0

27 Jun 13:34
ad77f99
Compare
Choose a tag to compare

What's Changed

This release contains significant new features such as allowing token based authentication to be refreshed, an SPI to role token based authentication with any provider via standard JDBC properties and more. Additionally we improved the callable statement support quite a bit, although it is probably not that widely used (yet).

Last but not least, the database metadata is now accurate wrt the return columns of procedures and functions and includes them in the corresponding methods.

🚀 Features

  • f6708c2 feat: Provide an authentication SPI and allow loading additional authentication suppliers via factories.
  • e09a250 feat: Add support for refreshing expiring token based authentication.

🐛 Bug Fixes

  • 3a620b3 fix: Align callable statement with JDBC spec wrt getting parameters back. (#1010)

🔄️ Refactorings

  • 88ec761 refactor: Include function and procedure return columns in metadata and add support for parameter metadata in callable statements. (#1012)
  • 466be62 refactor: Simplify Lazy<>.
  • 47e4193 refactor: SPIs must be exported from the bundles.
  • 94a196c refactor: Improve metrics collection.

📝 Documentation

  • 2d6bb9b docs: Update local changelog.

🧹 Housekeeping

  • ada99ed Bump org.neo4j:neo4j-cypher-dsl-bom to 2024.7.1
  • 8940670 Bump org.testcontainers:testcontainers-bom (#1003)
  • b5bdcdb Bump org.hibernate.orm:hibernate-platform (#997)
  • f975800 Bump quarkus.platform.version from 3.23.3 to 3.23.4 (#1004)
  • 117dbd6 Bump spring-boot.version from 3.5.0 to 3.5.3 (#1002)
  • 86d120f Bump com.opencsv:opencsv from 5.11.1 to 5.11.2 (#1001)
  • 6181140 Bump org.codehaus.mojo:flatten-maven-plugin (#1000)
  • b73d7f8 Bump dev.langchain4j:langchain4j-bom from 1.0.1 to 1.1.0 (#999)
  • e20b897 Bump com.puppycrawl.tools:checkstyle (#1005)
  • 7015668 Bump spring-javaformat.version from 0.0.46 to 0.0.47 (#998)
  • 003cedf Bump io.micrometer:micrometer-tracing-bom (#993)
  • 2b948a5 Bump org.jooq:jooq from 3.19.23 to 3.19.24 (#987)
  • 827309f Bump org.hibernate.orm:hibernate-platform (#988)
  • 521c6af Bump quarkus.platform.version from 3.23.2 to 3.23.3 (#990)
  • a76bb30 Bump org.neo4j:cypher-v5-antlr-parser from 5.26.7 to 5.26.8 (#991)
  • 87ce824 Bump com.fasterxml.jackson:jackson-bom (#992)
  • a14d8da Bump org.jdbi:jdbi3-bom from 3.49.4 to 3.49.5 (#994)
  • ac13f49 Bump io.micrometer:micrometer-bom from 1.15.0 to 1.15.1 (#995)

🛠 Build

  • 8cb67d8 build(test): Retrieve host from the KEYCLOAK container instead of defaulting to localhost.
  • 7fab110 build(docs): Updated antora dependencies.

6.5.1

12 Jun 14:33
Compare
Choose a tag to compare

What's Changed

🚀 Features

  • ed9a104 feat(translator): Add support for TOP n limited queries.
  • 52351f8 feat(translator): Add support for date extraction.

🔄️ Refactorings

  • 22de0b3 refactor: Make sure the driver works fine with Cypher 25 types. (#985)

📝 Documentation

  • e50ad26 docs: Include Cypher-backed views scheme fully in docs.

🧹 Housekeeping

  • 6f5d4b2 Bump org.codehaus.mojo:build-helper-maven-plugin (#984)
  • 98ae293 Bump spring-javaformat.version from 0.0.45 to 0.0.46 (#983)
  • 1c34907 Bump quarkus.platform.version from 3.23.0 to 3.23.2 (#980)
  • 878f24d Bump org.neo4j:cypher-v5-antlr-parser from 5.26.6 to 5.26.7 (#977)
  • acb0f7e Bump com.puppycrawl.tools:checkstyle (#976)
  • a1d2696 Bump com.opencsv:opencsv from 5.11 to 5.11.1 (#975)
  • f6a5a17 Bump org.testcontainers:testcontainers-bom (#974)
  • e29416b Bump org.codehaus.mojo:exec-maven-plugin (#973)
  • f6bd72d Bump org.neo4j:neo4j-cypher-dsl-bom (#972)
  • a8f5d3b Bump quarkus.platform.version from 3.22.3 to 3.23.0 (#970)
  • b0f5eab Bump spring-boot.version from 3.4.5 to 3.5.0 (#968)
  • 7eb8233 Bump org.mockito:mockito-bom from 5.17.0 to 5.18.0 (#967)
  • 03ab15d Bump org.hibernate.orm:hibernate-platform (#966)
  • 31bbb62 Bump dev.langchain4j:langchain4j-bom from 1.0.0 to 1.0.1 (#965)
  • 6bbd59f Bump io.github.git-commit-id:git-commit-id-maven-plugin (#964)
  • f0508ef Bump spring-javaformat.version from 0.0.44 to 0.0.45 (#963)
  • fbf3d88 Bump com.puppycrawl.tools:checkstyle (#962)

🛠 Build

  • 68e3e32 build: Propagate system properties starting with NEOJ4_ to the test container image.
  • b10c35b build: Allow inline return java docs.
  • 3f600c7 build: Add more jOOQ classes to build time initialization. (#961)
  • 0269ebc build: Make sure included single resources work in the AsciiDoc build.
  • d96af78 build: Shade JDK specific Jackson classes proper.

6.5.0

20 May 13:01
Compare
Choose a tag to compare

What's Changed

This is a feature release, introducing "Cypher-backed views" . Cypher-backed views will help you teaching your tools all the capabilities of Cypher without those tools leaving the relational world. Please have a look at the documentation linked above.

In this release we also took some time and polish up the code base a bit, addressing some technical debt, resulting in a quadruple A-rating at the Neo4j SonarQube instance with regards to security, reliability, maintainability and security hotspots.

If you have feedbacks, issues, bugs: Please reach out on the issue tracker.

🚀 Features

  • 90900b1 feat: Support Cypher-backed views. (#946)
  • 8f7be33 feat: Provide a dedicated logger for processed SQL.

🐛 Bug Fixes

  • e7c91fc fix: Rewriting of parameter placeholders for prepared statements.

🔄️ Refactorings

  • 8f69a6b refactor: Don’t default password to password
  • ffc010f refactor: Correct typographic error.
  • 9d0084e refactor: Use dedicated method for querying apoc availibility.

📝 Documentation

  • 5b3d038 docs: Polish named parameters example. (#959)
  • 23987e7 docs: Document Cypher-backed views in README.
  • f644fef docs: Update local changelog.
  • 0609ce4 docs: Fix copyright year in Antora config.
  • e275046 docs: Fix typographic error in CONTRIBUTING. (#939)

🧹 Housekeeping

  • 6666f0f Bump com.puppycrawl.tools:checkstyle from 10.21.4 to 10.23.1 (#928)
  • 4d809ce Bump org.jetbrains.kotlin:kotlin-stdlib-jdk8 (#954)
  • 71cc907 Bump io.micrometer:micrometer-bom from 1.14.6 to 1.15.0 (#953)
  • edd4dc5 Bump com.fasterxml.jackson.jr:jackson-jr-objects (#956)
  • 2ec5579 Bump quarkus.platform.version from 3.22.2 to 3.22.3 (#955)
  • ebaad65 Bump org.jdbi:jdbi3-bom from 3.49.3 to 3.49.4 (#952)
  • 90ca425 Bump dev.langchain4j:langchain4j-bom from 0.36.2 to 1.0.0 (#951)
  • aaed5a7 Bump io.micrometer:micrometer-tracing-bom (#950)
  • 10c33f7 Bump spring-javaformat.version from 0.0.43 to 0.0.44 (#949)
  • 970f3f9 Bump org.hibernate.orm:hibernate-platform (#948)
  • 2d5c565 Bump org.neo4j:neo4j-cypher-dsl-bom to 2024.6.1
  • 9e07ea7 Bump org.neo4j:neo4j-cypher-dsl-bom (#945)
  • 93c8012 Bump org.neo4j:cypher-v5-antlr-parser from 5.26.5 to 5.26.6 (#944)
  • 5027104 build(deps-dev): Bump com.tngtech.archunit:archunit from 1.4.0 to 1.4.1 (#943)
  • 66528b5 Bump quarkus.platform.version from 3.22.1 to 3.22.2 (#942)
  • c59da14 Update neo4j-bolt-connection to 3.0.0 (#940)

🛠 Build

  • ccdd229 build: Incorporate Spring Boot smoke tests into test results.
  • bb02ce6 build: Make sure integration tests are observed by Sonar. (#957)
  • 1faf4fc build: Integrate deploy configuration for JReleaser with Maven and document all necessary deploy steps.
  • 12ede47 build: Exclude the text2cypher PoC / experimental module from code coverage.

6.4.1

06 May 19:42
Compare
Choose a tag to compare

What's Changed

This release does neither include changes nor dependency updates, but addresses the issue of the missing SBOMs in Maven central:

They are now available and look like this (for the core module): neo4j-jdbc-6.4.1-sbom-cyclonedx.json.

6.4.0

05 May 13:36
Compare
Choose a tag to compare

What's Changed

(Note: Publishing SBOMs failed, but they can be created and will be in the next release)

🚀 Features

  • 38dae9f feat: Provide access to GQL Status objects.
  • b72778b feat: Propagate GQL error codes as SQL state. (#932)
  • d631b45 feat: Generate and attach CycloneDX SBOMs for all relevant artifacts. (#931)
  • bbd7f29 feat: Add support for java.sql.Array.

🐛 Bug Fixes

  • 47032b6 fix: Neo4j FLOAT is a SQL Double, INTEGER is BIGINT.

🔄️ Refactorings

  • d2f03d9 refactor: Polish some JavaDocs, deprecate methods and fields that should never have been public.

🧹 Housekeeping

  • b0011ef Bump org.jooq:jooq from 3.19.22 to 3.19.23 (#936)
  • 8735bbd Bump com.opencsv:opencsv from 5.10 to 5.11 (#938)
  • 7b977c1 Bump org.jreleaser:jreleaser-maven-plugin (#937)
  • bbd328f Bump quarkus.platform.version from 3.21.4 to 3.22.1 (#935)
  • ba830c7 Bump org.jdbi:jdbi3-bom from 3.49.2 to 3.49.3 (#934)
  • 104261a Bump org.openapitools:openapi-generator-maven-plugin (#929)
  • a5e13b5 Bump org.jdbi:jdbi3-bom from 3.49.0 to 3.49.2 (#927)
  • dad329b Bump org.testcontainers:testcontainers-bom (#926)
  • dc44d00 Bump quarkus.platform.version from 3.21.2 to 3.21.4 (#925)
  • 35d5103 Bump spring-boot.version from 3.4.4 to 3.4.5 (#924)
  • 2b4d929 Bump io.micrometer:micrometer-tracing-bom (#922)
  • 28d0206 Bump org.neo4j.bolt:neo4j-bolt-connection-bom (#930)