Spring 4 + Neo4j Integration Annotation Example with Gradle
December 20, 2014
In this page we will learn the integration of Spring 4 with Neo4j. Neo4j is a database which stores data in graph format. Neo4j is open source and can be used effectively in spring application. We can easily install and use it within our application. Neo4j provides UI to run queries that is also known as cypher. We need to create entities using @NodeEntity annotation provided by spring. To fetch the graph database, we have to create our repository with useful methods. Spring needs a bean named as graphDatabaseService which will be defined to get connection. Neo4j graph database server uses rest web services to interact with other application for database transaction.
What we are going to do in this example is that, we have a student entity. We will create some students and define a seniority relationship and save data. Then using student name we will fetch our data from graph database. We will also run cypher query on Neo4j UI to get the graph for our data at the end.
Software Required to Run Example
To run the example we need the software as below.1. JDK 6
2. Gradle
3. Neo4j Graph Database
4. Eclipse
Install Neo4j Database
To install Neo4j, go to neo4j.com and download Neo4j. After installation choose a database location. In my case, database location is C:\neo4j\data. Start the database server and access it using URL http://localhost:7474 . You can run here cypher queries i.e queries to create and access Neo4j graph database.Project Structure in Eclipse
Find the project structure in eclipse. We will be using Entity, Repository, Configuration classes to build the application.Create Entity with @NodeEntity, @GraphId, @Fetch and @RelatedTo
In our example we are creating a student entity. For this, we need to use below annotations from org.springframework.data.neo4j.annotation API.@NodeEntity : Declares a class as pojo entity for graph database.
@GraphId : Declares Id field for graph entity.
@Fetch: If using @Fetch annotation, eagerly loading is enabled.
@RelatedTo : Declares a relation with other entity. It can be one-to-one and one-to-many relationship. The relation type can be defined anything like real life relation as BROTHER, SISTER, FRIEND etc. The direction can be INCOMING, OUTGOING or BOTH.
Student.java
package com.concretepage.neo4j.entity; import java.util.HashSet; import java.util.Set; import org.neo4j.graphdb.Direction; import org.springframework.data.neo4j.annotation.Fetch; import org.springframework.data.neo4j.annotation.GraphId; import org.springframework.data.neo4j.annotation.NodeEntity; import org.springframework.data.neo4j.annotation.RelatedTo; @NodeEntity public class Student { @GraphId Long id; public String name; @Fetch @RelatedTo(type="SENIOR", direction=Direction.BOTH) public Set<Student> seniors; public Student(){} public Student(String name){ this.name=name; } public void mySeniors(Student student){ if(seniors == null) { seniors = new HashSet<Student>(); } seniors.add(student); } }
Create Repository Using CrudRepository and @Query
To access data according to our requirement we need to write a Repository interface where we will declare our methods. Method will be annotated with @Query using which we will write cypher query to access data from graph database.StudentRepository.java
package com.concretepage.neo4j; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.CrudRepository; import com.concretepage.neo4j.entity.Student; public interface StudentRepository extends CrudRepository<Student, String> { @Query("Match (student:Student) Where student.name = {0} return student") Student getStudentByName(String name); @Query("match (student:Student)-[:SENIOR]-> seniorStudents where student.name= {0} return seniorStudents") Iterable<Student> getSeniorsByStudentName(String name); }
Create Configuration Class Using @EnableNeo4jRepositories and GraphDatabase
To get graph database connection and define our graph entity, we need to write Configuration class. This class must be annotated with @EnableNeo4jRepositories which takes basePackages as a parameter. There must be a bean with name graphDatabaseService that will return GraphDatabaseService object which is used by GraphDatabase instance to save and query our data with graph database.AppConfig.java
package com.concretepage.neo4j.config; import org.neo4j.graphdb.GraphDatabaseService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.config.Neo4jConfiguration; import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.rest.SpringRestGraphDatabase; import com.concretepage.neo4j.StudentRepository; @Configuration @EnableNeo4jRepositories(basePackages = "com.concretepage.neo4j") public class AppConfig extends Neo4jConfiguration { public AppConfig() { setBasePackage("com.concretepage.neo4j"); } @Autowired GraphDatabase graphDatabase; @Autowired StudentRepository studentRepository; @Bean GraphDatabaseService graphDatabaseService() { return new SpringRestGraphDatabase("http://localhost:7474/db/data"); } }
Main Class Using Neo4j save() Method
Now we will create our main class to run the example. Here in this class we will create instances of some students and then will define seniority a relationship among them. Do the following steps.1. Begin graph database transaction using GraphDatabase.beginTx
2. If need to delete old data of entity, call deleteAll using repository instance.
3. Once work is done, call Transaction.success that will mark the transaction successful and will save data in graph on the call of Transaction.close.
4. Finally call, Transaction.close that will commit the data or mark the transaction for rollback if any error.
Main.java
package com.concretepage.neo4j; import org.neo4j.graphdb.Transaction; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.neo4j.core.GraphDatabase; import com.concretepage.neo4j.config.AppConfig; import com.concretepage.neo4j.entity.Student; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); GraphDatabase graphDatabase = (GraphDatabase)ctx.getBean("graphDatabase"); StudentRepository studentRepository = ctx.getBean(StudentRepository.class); Transaction tx = graphDatabase.beginTx(); Student ram = new Student("Ram"); Student shyam = new Student("Shyam"); Student mohan = new Student("Mohan"); Student krishn = new Student("Krishn"); try { //Delete if exists already studentRepository.deleteAll(); //Save student studentRepository.save(ram); studentRepository.save(shyam); studentRepository.save(mohan); //Build Relation krishn.mySeniors(mohan); krishn.mySeniors(ram); krishn.mySeniors(shyam); studentRepository.save(krishn); //Get Student By Name Student s = studentRepository.getStudentByName(ram.name); System.out.println(s.name); //Fetch all seniors of student Iterableseniors = studentRepository.getSeniorsByStudentName(krishn.name); System.out.println("----Seniors----"); for (Student student : seniors) { System.out.println(student.name); } tx.success(); } finally { tx.close(); } } }
Ram ----Seniors---- Ram Shyam Mohan
Output in Neo4j Graph Database
Go to http://localhost:7474 and run cypher as belowMATCH (student:Student) RETURN student
Gradle for Spring 4 and Neo4j Jar
Find the gradle build file used in demo.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'Concretepage' version = '1.0-SNAPSHOT' repositories { maven { url "https://repo.spring.io/libs-release" } mavenLocal() mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter:1.1.9.RELEASE' compile 'org.springframework:spring-context:4.1.2.RELEASE' compile 'org.springframework:spring-tx:4.1.2.RELEASE' compile 'org.springframework.data:spring-data-neo4j:3.2.1.RELEASE' compile 'org.springframework.data:spring-data-neo4j-rest:3.2.1.RELEASE' compile 'org.hibernate:hibernate-validator:5.2.0.Alpha1' compile 'org.neo4j:neo4j-rest-graphdb:2.0.1' compile 'javax.enterprise:cdi-api:1.2' }