Java

Prerequisites

  • Java 1.8+

Installation

Download the latest version of the Neo4j Java Driver along with the compatible version of Reactive Streams into your working directory.

To download the latest version of the Neo4j Java Driver:

  1. Navigate to the Neo4j Java Driver page of Maven Central.

  2. Select the latest version at the top of the list.

  3. Select Downloads from the top right of the page and then select jar to download the jar file.

To download the compatible version of Reactive Streams:

  1. Navigate to the Maven Central page of the version of the Neo4j Java Driver you previously downloaded.

  2. Find the reactive-streams artifact dependency in the pom.xml file on the left side of the page to find the version.

  3. Navigate to the Reactive Streams page of Maven Central.

  4. Select the same version as the one present in the pom.xml file previously.

  5. Select Downloads from the top right of the page and then select jar to download the jar file.

Code example

import org.neo4j.driver.*;
import org.neo4j.driver.Record;
import org.neo4j.driver.exceptions.Neo4jException;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import static org.neo4j.driver.Config.TrustStrategy.trustAllCertificates;

public class DriverIntroductionExample implements AutoCloseable {
    private static final Logger LOGGER = Logger.getLogger(DriverIntroductionExample.class.getName());
    private final Driver driver;

    public DriverIntroductionExample(String uri, String user, String password, Config config) {
        // The driver is a long living object and should be opened during the start of your application
        driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config);
    }

    @Override
    public void close() throws Exception {
        // The driver object should be closed before the application ends.
        driver.close();
    }

    public void createFriendship(final String person1Name, final String person2Name) {
        // To learn more about the Cypher syntax, see https://neo4j.com/docs/cypher-manual/current/
        // The Reference Card is also a good resource for keywords https://neo4j.com/docs/cypher-refcard/current/
        String createFriendshipQuery = "CREATE (p1:Person { name: $person1_name })\n" +
                "CREATE (p2:Person { name: $person2_name })\n" +
                "CREATE (p1)-[:KNOWS]->(p2)\n" +
                "RETURN p1, p2";

        Map<String, Object> params = new HashMap<>();
        params.put("person1_name", person1Name);
        params.put("person2_name", person2Name);

        try (Session session = driver.session()) {
            // Write transactions allow the driver to handle retries and transient errors
            Record record = session.writeTransaction(tx -> {
                Result result = tx.run(createFriendshipQuery, params);
                return result.single();
            });
            System.out.println(String.format("Created friendship between: %s, %s",
                    record.get("p1").get("name").asString(),
                    record.get("p2").get("name").asString()));
        // You should capture any errors along with the query and data for traceability
        } catch (Neo4jException ex) {
            LOGGER.log(Level.SEVERE, createFriendshipQuery + " raised an exception", ex);
            throw ex;
        }
    }

    public void findPerson(final String personName) {
        String readPersonByNameQuery = "MATCH (p:Person)\n" +
                "WHERE p.name = $person_name\n" +
                "RETURN p.name AS name";

        Map<String, Object> params = Collections.singletonMap("person_name", personName);

        try (Session session = driver.session()) {
            Record record = session.readTransaction(tx -> {
                Result result = tx.run(readPersonByNameQuery, params);
                return result.single();
            });
            System.out.println(String.format("Found person: %s", record.get("name").asString()));
        // You should capture any errors along with the query and data for traceability
        } catch (Neo4jException ex) {
            LOGGER.log(Level.SEVERE, readPersonByNameQuery + " raised an exception", ex);
            throw ex;
        }
    }

    public static void main(String... args) throws Exception {
        // Aura queries use an encrypted connection using the "neo4j+s" protocol
        String uri = "neo4j+s://<Bolt url for Neo4j Aura instance>";
        String user = "<Username for Neo4j Aura instance>";
        String password = "<Password for Neo4j Aura instance>";

        try (DriverIntroductionExample app = new DriverIntroductionExample(uri, user, password, Config.defaultConfig())) {
            app.createFriendship("Alice", "David");
            app.findPerson("Alice");
        }
    }
}

Running the example

Follow the steps below to run the example code:

  1. Copy and paste the code above into a file named DriverIntroductionExample.java.

  2. Enter the information for the AuraDB instance you want to connect to by replacing:

    • <Bolt url for Neo4j Aura instance> with the URI.

    • <Username for Neo4j Aura instance> with the username.

    • <Password for Neo4j Aura instance> with the password.

  3. Use the following command to compile the java file, replacing <driver-version> with your installed driver version:

    javac -cp neo4j-java-driver-<driver-version>.jar DriverIntroductionExample.java
  4. Use the following command to run the example code, replacing <driver-version> with your installed driver version and <rs-version> with your installed Reactive Streams version:

    java -cp neo4j-java-driver-<driver-version>.jar:reactive-streams-<rs-version>.jar:. DriverIntroductionExample

Example walkthrough

The example imports neo4j.driver to connect to the Neo4j AuraDB instance.

The main function calls the following two functions:

  • createFriendship creates two 'Person' nodes, Alice and David, and a 'KNOWS' relationship between them using a write transaction.

  • findPerson finds Alice using a read transaction.

Developing with Neo4j Aura requires the handling of transient errors and retry management. One of the ways you can meet this requirement is by using Transaction Functions.

Make sure to log queries and data sent from your application as it is useful when you encounter errors and can help with debugging.