Developer Guides Getting Started Getting Started What is a Graph Database? Intro to Graph DBs Video Series Concepts: RDBMS to Graph Concepts: NoSQL to Graph Getting Started Resources Neo4j Graph Platform Graph Platform Overview Neo4j Desktop Intro Neo4j Browser Intro… Read more →
Spring Data Neo4j
For Java developers who use the Spring Framework or Spring Boot, this guide introduces Spring integration through the Spring Data Neo4j library. The library provides convenient access to Neo4j including object mapping, Spring Data repositories, conversion, transaction handling, and more.
You should be familiar with graph database concepts and the property graph model. Having installed Neo4j and tried out the Cypher query language helps too. You should also be familiar with Spring. Knowing Spring Data and Spring Boot are both great additions to your toolbox, as well. When developing with Neo4j, please use JDK 8 or later and your favorite IDE.
Neo4j offers a rich set of possibilities for developers using Spring. If you are looking to use Neo4j on the JVM in general, the Java developer’s guide explains from that perspective. However, if you want to benefit from full-fledged object mapping and the other helpful support that comes with Spring Data, this guide shows how to do that with Spring Data Neo4j.
Neo4j’s Spring Data integration was the founding project of the Spring Data efforts, started by Rod Johnson and Emil Eifrem. It is built on Spring Framework and also offers Object-Graph Mapping (OGM) on top of Neo4j.
Spring Data Neo4j is also supported by Spring Boot. You can use the Spring Initializr page to get started with Spring Data Neo4j immediately.
Though Spring Data Neo4j has been around for a long time, Neo4j’s APIs and usage evolved quickly from an embedded, Java-only database to a server solution with mostly Cypher interactions.
To use Spring Data Neo4j, all you need is the Spring Data Neo4j dependencies and a few annotations to use the object-graph mapping. Then, you can annotate your entities and define your Spring Data repositories as convenient interfaces to your persistence layer.
- Spring Boot integration
- Annotation-based object-graph mapping
- Interface-based repository support with annotated and derived finder methods
- Fast class metadata scanning
- Optimized management of data loading and change tracking for minimal data transfers
- Multiple transports – binary protocol, HTTP, and embedded
- Persistence lifecycle events
Spring Boot takes on much of the responsibility of application configuration and bootstrap, so we have chosen to take advantage of that assistance in our project for this guide. The example project code for Spring Data Neo4j is in GitHub. You can clone the repository and run the code along with this guide, or you can build the project from the ground up from the Spring Initializr page.
We will be using the movie domain that you may already be familiar with – people (actors, directors, etc) and the movies those people are involved in.
First, the dependency for Spring Data Neo4j needs to be in the dependency file to use the capabilities.
Here, we are using Maven, the dependency file is a
The entities outline our main objects in the application. In our graph, they will be the nodes.
There is a
Person entity and a
Movie entity, so a domain class for each is needed.
The first few lines of each domain class are shown below.
Each class is annotated with
@NodeEntity to use these objects as nodes in the graph.
Each contains an id field that is annotated as the
id and populated with a value generated by the database (
id, additional fields are set up to hold different information we want to capture about the object.
Now we need to add lines in each class to map the relationships between the nodes.
In our graph data, movies and people are connected by a few different relationships –
ACTED_IN relationship, we store a relationship property that contains a list of the role(s) that the person played in a specific movie.
We will need to create a relationship entity to tie it to the node entities for
Person and capture the additional attributes about the
We create a relationship entity called
Role to connect
Person to a
Movie by the
Role he/she played.
We annotate this new class as a relationship entity (
@RelationshipEntity) and specify the name of the relationship (
Role class also has an id field that is managed by the database and a List type field to contain the possible roles that a person could play in a movie (could be more than one).
Then, annotations are added to mark the
Movie nodes as start node and end node for the relationship.
Reference fields in both the
Movie classes have annotations with
@Relationship and the relationship types as
The direction property is outgoing by default, so we must specify that the relationships are incoming on the
Finally, because these entities are all connected together, when we pull one entity in a request, it will pull the rest. When it pulls the other entities, it will follow the relationships back to the starting entity, which will go back to the related entities, creating a round-robin infinite recursion loop. To avoid this error, we can add an annotation to ignore certain fields when it traverses the relationships.
@JsonIgnoreProperties annotation is put on all the relationship variables to ignore the fields on the next entity that connect back, avoiding infinite recursion errors and duplicate information returning.
We now have our graph structure mapped in our application.
This is the object-graph mapping (OGM) piece.
The repository interface allows the developer to create methods and queries for retrieving the data from the database.
The interfaces extend the
Neo4jRepository, which extend the Spring CRUD repository for persisting and retrieving data.
CRUDRepository, a lot of CRUD methods (such as
delete, etc.) come already out-of-the-box.
So, without even having to specify any method, basic data access is provided.
However, we want to define a few specific methods, which are shown below.
Let’s start with our
The first two methods are defined in a specific pattern so that the queries can be derived for us (like the
These will allow us to search for specific people in our graph by providing a name or search string to the request to retrieve either a single result (
getPersonByName) or a list of potential matches (
Other methods must be specifically written and annotated with
@Query, which is how our last query is defined.
In this case, we want to retrieve
Person nodes who have acted in and directed movies.
The custom query we defined using Cypher will retrieve the
Person results, along with that individual’s relationships and movies.
For more information, see the Spring Data Neo4j documentation.
MovieRepository, we will only define a couple of methods that can be derived for us.
As with our
PersonRepository above, these methods in our
MovieRepository will allow us to search for a specific movie title or retrieve a list of possible matches.
For a more thorough walkthrough of the code, see the resources linked below. We also provide reactive development through the Spring Data Neo4j RX project.
The Neo4j, GraphAware, and Pivotal teams.