Java client guide
Learn how to create a Java application that connects to the Memgraph database and executes simple queries.
Memgraph currently depends on the Neo4j Java driver. Memgraph and Neo4j both support Bolt protocol and Cypher queries, which means that same driver can be used to connect to both databases. This is very convenient if switching between the two databases is needed. This guide is based on the driver version v5 and above. Some examples may not be supported in older versions of the driver.
Quickstart
The following guide will demonstrate how to start Memgraph, connect to Memgraph, seed the database with data, and run simple read and write queries.
Necessary prerequisites that should be installed in your local environment are:
Java client API usage and examples
After a brief Quickstart guide, this section will go into more detail on how to use the Java driver API, explain code snippets, and provide more examples. Feel free to skip to the section that interests you the most.
Database connection
Once the database is running and the driver is installed or available in Java, you should be able to connect to the database in one of two ways::
Connect without authentication (default)
By default, the Memgraph database is running without authentication, which means that you can connect to the database without providing any credentials (username and password). To connect to Memgraph, create a driver object with the appropriate URI and credentials arguments. If you’re running Memgraph locally, the URI should be similar to , and if you are running Memgraph on a remote server, replace with the appropriate IP address. If you ran Memgraph on a port different than 7687, do not forget to update that in the URI too.
By default, you can set the username and password in the argument as empty strings. This means that you are connecting without authentication.
To connect a Java driver to the Memgraph database, you can use the following snippet:
Notice that takes two arguments, the first is and the second is . For both username and password, you can pass an empty string, this means that you are connecting without authentication.
Connect with authentication
In order to set up authentication in Memgraph, you need to create a user with a and . In Memgraph you can set a username and password by executing the following query:
Then, you can connect to the database with the following snippet:
You may receive this error:
The error indicates that you have probably enabled authentication in Memgraph, but are trying to connect without authentication. For more details on how to set authentication further, visit the Memgraph authentication guide.
Java client connection lifecycle management
Once the driver connection to Memgraph is established, it doesn’t need to be closed. It’s sufficient to open a single client connection to Memgraph and use it for all queries. Once the client connection is open, the lifecycle can be managed using the Java AutoCloseable interface. The client’s lifetime is tied to the application lifecycle.
The following implementation of interface will make sure to close the client connection once the application is finished:
Keep in mind that the driver object is thread-safe and can be reused between different threads.
Query the database
After connecting your driver to Memgraph you can start running queries. The simplest way to run the query is via and methods.
Run a write query
The following query will create a node inside the database:
The session object takes a object as its argument. The object is used to specify the database name and other session configuration options. Session API supports and methods. The method takes a functional interface as its argument. The interface has a single method , which takes a Transaction object as its argument and returns a value of generic type , in this case.
Run a read query
Similar to the write query, method can be used to run read queries. The difference is that read will return the results of the query.
The following query will read data from the database:
In the above query, each contains a accessible by the method.
Running queries with property map
If you want to pass a property map to the query, you can do it like this:
Using this approach, the queries will not contain hard-coded values, they can be more dynamic.
Process the results
In order to serve the read results back to the Java application, their types need to be handled properly because Java is a statically typed language. Depending on the type of request made, you can receive different results. Let’s go over a few basic examples of how to handle different types and access properties of the returned results.
Process the Node results
Run the following query:
Records field contains all the records returned by the query. To process the results, you can iterate over the records and access the fields you need.
Here is an example:
In the example above, each returned is converted into a map. From the map, you can access the field, which is a returned from a query. The returned record and all its properties are of type . This means you must cast them to the relevant Java type if you want to use methods or features defined on such types.
You can access individual properties of the using one of the following options:
You can access all properties by casting and accessing . Keep in mind that the returns the internal ID of the node, which is not the same as the user-defined ID, and it should not be used for any application-level logic.
Processing Relationship results
You can also receive a from the query. For example:
You can access properties in the same way as you access the properties. ID values from and methods are the internal IDs of the start and end node of the relationship. Do not use them in your application logic.
Processing Path results
You can receive from the database, using the following construct:
Path will contain Nodes and [Relationships[#process-the-relationship-result], that can be accessed in the same way as in the previous examples, by casting them to the relevant type.
Types mapping Cypher and Java
Here is the full table of the mapping between Memgraph Cypher types and the types used in the Java driver:
Keep in mind that, at the moment, Memgraph does not support Timezones, ByteArray and Point.
Transaction management
Transaction is a unit of work that is executed on the database, it could be some basic read, write or complex set of steps in form of series of queries. There can be multiple ways to mange transaction, but usually, they are managed automatically by the driver or manually by the explicit code steps. Transaction management defines how to handle the transaction, when to commit, rollback, or terminate it.
On the driver side, if a transaction fails because of a transient error, the transaction is retried automatically. The transient error will occur during write conflicts or network failures. The driver will retry the transaction function with an exponentially increasing delay.
Simple transaction management
Simple transaction management provides a standard blocking style API for Cypher execution. It also provides the most straightforward programming style to work with since API calls are executed strictly sequentially.
Session management
Before doing any transaction management, you need to create a session. A session is a specific connection to the database that can live for a certain period. The session connection is lightweight and should be closed after the wanted queries have been executed instead of keeping it open for the whole duration of the application. To open a session, use the code snippet below:
The Java “try-with-resources” statement will automatically close the session once the code block is finished. Sessions are not thread-safe, so you should create a new session for each thread.
You can use the following transaction management methods with sessions:
- - executes a managed explicit transaction workload in write access mode with retry logic.
- - executes a managed explicit transaction workload in read access mode with retry logic.
- - executes a implicit auto-commit transaction and returns result.
Managed transactions
Let’s look at the basic example of reading data from the database. Run a simple transaction using the :
All the previous examples from this guide have used simple transaction management. It allows you to run multiple queries in a single transaction and have control over the transaction. You could have multiple logic blocks in the transaction, rollback or end the transaction if needed. Also, managed transactions have a retry logic, which means that if the transaction fails, it will be retried. Managed transactions are the most flexible way to run a Cypher query.
Implicit transactions
Implicit auto-commit queries are the simplest way to run a Cypher query since they aren’t automatically retried like and are. With implicit auto-commit transactions, you don’t have the same control of transactions as with managed explicit transactions.
Here is an example of an implicit transaction:
The above code runs a simple query without any transaction management. It simplifies the experience, but you lose flexibility when running queries. Since explicit transactions are multi-statement transactions, creating an index, constraints or auth config queries is not possible in multi-line transactions. Therefore, you need to use implicit transactions for those queries.
Asynchronous transaction management
Asynchronous transactions management provides an API to work with s in transactions. The class represents a future result of an asynchronous computation in Java. This result will eventually appear in the after the processing is complete. This allows client applications to work within asynchronous code bases while managing transactions.
Session management
Asynchronous sessions provide an API to work with . Asynchronous sessions are not thread-safe, so you should create a new session for each thread. Session lifetime begins with session construction, and the session is typically closed automatically when all results are consumed. The session is opened using the following code snippet:
You can use the following transaction management methods via async session API:
- - executes a managed transaction workload in write access mode with retry logic.
- - executes a managed transaction workload in read access mode with retry logic.
- - executes a implicit auto-commit transaction and returns result.
Managed transactions
Here is a basic example of reading data from the database via Async session API:
Implicit auto-commit asynchronous transactions
Implicit auto-commit queries are the simplest way to run a Cypher query since they aren’t automatically retried like and are.
Here is an example of an implicit transaction: