Skip to content

Commit 865729d

Browse files
author
Rakesh Venkatesh
committed
changes
1 parent 415d39c commit 865729d

File tree

38 files changed

+1868
-0
lines changed

38 files changed

+1868
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
target
3+
*.iml
4+
*.class
5+
*.jar
6+
*.pyc
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
Movies Example Application
2+
==========================
3+
4+
How to use Spring Boot, Spring Data, and Neo4j together.
5+
6+
Spring Data Neo4j enables convenient integration of Neo4j in your Spring-based application.
7+
It provides object-graph mapping (OGM) functionality and other features common to the Spring Data projects.
8+
9+
[NOTE]
10+
*This project uses Spring Data Neo4j 5.*
11+
It is optimized for working with Neo4j Desktop and based on Neo4j's query language, Cypher.
12+
13+
The example project is described in detail on the https://neo4j.com/developer/example-project/[Neo4j Developer Site]
14+
15+
== Quickstart
16+
17+
. http://neo4j.com/download[Download, install, and start Neo4j Desktop].
18+
. From here, there are two ways you can access the end points.
19+
1) Open the browser web interface at http://localhost:7474
20+
a. Configure a username and password, if you haven't already.
21+
2) In Neo4j Desktop, click on your project, click on 'Manage' on the database you are using, click 'Open Browser'.
22+
a. Should not need to log in. Password was set up when you set up the database.
23+
. Run `:play movies` command, and click and run the Cypher statement to insert the dataset
24+
. Clone this project from GitHub
25+
. Update `src/main/resources/application.properties` with the username and password you set above.
26+
. Run the project with `mvn spring-boot:run`.
27+
28+
== Code Walkthrough
29+
30+
To use Neo4j with Spring Data Neo4j, you just add the dependency for https://projects.spring.io/spring-boot/[Spring-Boot] and https://projects.spring.io/spring-data-neo4j/[Spring-Data-Neo4j] to your build setup.
31+
32+
.pom.xml
33+
[source,xml]
34+
----
35+
<dependency>
36+
<groupId>org.springframework.boot</groupId>
37+
<artifactId>spring-boot-starter-data-neo4j</artifactId>
38+
</dependency>
39+
----
40+
include::pom.xml[tags=dependencies]
41+
42+
Annotate your `@NodeEntity` and `@RelationshipEntity`. You can use the OGM `Session` to access Neo4j APIs and object graph mapping functionality.
43+
44+
.Movie.java
45+
[source,java]
46+
----
47+
@NodeEntity
48+
public class Movie {
49+
50+
@Id
51+
@GeneratedValue
52+
private Long id;
53+
54+
private String title;
55+
56+
private int released;
57+
58+
private String tagline;
59+
60+
@Relationship(type = "ACTED_IN", direction = Relationship.INCOMING)
61+
private List<Role> roles;
62+
}
63+
----
64+
include::src/main/java/movies/spring/data/neo4j/domain/Movie.java[tags=movie]
65+
66+
Additionally, you can leverage the convenient Spring-Data repositories to get interface-based DAO implementations injected into your Spring Components.
67+
68+
.MovieRepository.java
69+
[source,java]
70+
----
71+
public interface MovieRepository extends Neo4jRepository<Movie, Long> {
72+
73+
Movie findByTitle(@Param("title") String title);
74+
75+
Collection<Movie> findByTitleLike(@Param("title") String title);
76+
77+
@Query("MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m,r,a LIMIT {limit}")
78+
Collection<Movie> graph(@Param("limit") int limit);
79+
}
80+
----
81+
include::src/main/java/movies/spring/data/neo4j/repositories/MovieRepository.java[tags=repository]
82+
83+
In our case, we use the repository from a `MovieService` to compute the graph representation for the visualization.
84+
The service is then injected into our main Boot application, which also doubles as `@RestMvcController` which exposes the `/graph` endpoint.
85+
86+
The other two endpoints for finding multiple movies by title and loading a single movie are provided out of the box by the https://projects.spring.io/spring-data-rest/[Spring-Data-Rest project], which exposes our `MovieRepository` as REST endpoints.
87+
88+
The rendering of the movie objects (and related entities) happens automatically via Jackson mapping.
89+
90+
== The Stack
91+
92+
These are the components of our Web Application:
93+
94+
* Application Type: Spring-Boot Java Web Application (Jetty)
95+
* Web framework: Spring-Boot enabled Spring-WebMVC, Spring-Data-Rest
96+
* Persistence Access: Spring-Data-Neo4j 5.0.5
97+
* Database: Neo4j-Server 3.3.x
98+
* Frontend: jquery, bootstrap, http://d3js.org/[d3.js]
99+
100+
== Endpoints:
101+
102+
Get Movie
103+
104+
To run our setup queries through our REST endpoints:
105+
106+
From the Neo4j Desktop main console, go to 'Manage' on your database, then choose the 'Terminal' tab. You can copy/paste the commands below into that terminal and should see results.
107+
108+
You can also go to http://localhost:8080 to interact with the data.
109+
110+
Now feel free to add other queries to your application to see more data and relationships!
111+
112+
----
113+
// JSON object for single movie with cast
114+
curl http://localhost:8080/movies?title=The%20Matrix
115+
116+
// list of JSON objects for movie search results
117+
curl http://localhost:8080/movies?title=*matrix*
118+
119+
// JSON object for whole graph viz (nodes, links - arrays)
120+
curl http://localhost:8080/graph
121+
----
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>com.neo4j.examples</groupId>
7+
<artifactId>sdn5-movies</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<packaging>jar</packaging>
10+
11+
<name>SDN5 Movies</name>
12+
<description>Demo web project for Spring Data using Spring Boot and Neo4j</description>
13+
14+
<parent>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-parent</artifactId>
17+
<version>2.2.4.RELEASE</version>
18+
</parent>
19+
20+
<properties>
21+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
22+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
23+
<java.version>1.8</java.version>
24+
<neo4j-ogm.version>3.2.8</neo4j-ogm.version>
25+
</properties>
26+
27+
<dependencies>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-web</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-data-neo4j</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-data-rest</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.springframework.boot</groupId>
42+
<artifactId>spring-boot-devtools</artifactId>
43+
</dependency>
44+
<dependency>
45+
<groupId>org.springframework.boot</groupId>
46+
<artifactId>spring-boot-starter-test</artifactId>
47+
<scope>test</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>org.neo4j</groupId>
51+
<artifactId>neo4j</artifactId>
52+
<version>3.5.14</version>
53+
<scope>runtime</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.neo4j</groupId>
57+
<artifactId>neo4j-ogm-embedded-driver</artifactId>
58+
<version>${neo4j-ogm.version}</version>
59+
<scope>test</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.neo4j</groupId>
63+
<artifactId>neo4j-ogm-bolt-driver</artifactId>
64+
<version>${neo4j-ogm.version}</version>
65+
</dependency>
66+
</dependencies>
67+
68+
<build>
69+
<plugins>
70+
<plugin>
71+
<groupId>org.springframework.boot</groupId>
72+
<artifactId>spring-boot-maven-plugin</artifactId>
73+
</plugin>
74+
</plugins>
75+
</build>
76+
77+
</project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package movies.spring.data.neo4j;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.boot.autoconfigure.domain.EntityScan;
6+
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
7+
import org.springframework.transaction.annotation.EnableTransactionManagement;
8+
9+
/**
10+
* @author Michael Hunger
11+
* @author Mark Angrish
12+
*/
13+
@SpringBootApplication
14+
@EnableNeo4jRepositories("movies.spring.data.neo4j.repositories")
15+
public class SampleMovieApplication {
16+
17+
public static void main(String[] args) {
18+
SpringApplication.run(SampleMovieApplication.class, args);
19+
}
20+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package movies.spring.data.neo4j.controller;
2+
3+
import java.util.Collection;
4+
import java.util.Map;
5+
6+
import movies.spring.data.neo4j.domain.Movie;
7+
import movies.spring.data.neo4j.services.MovieService;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestParam;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
/**
15+
* @author Mark Angrish
16+
* @author Michael J. Simons
17+
*/
18+
@RestController
19+
@RequestMapping("/")
20+
public class MovieController {
21+
22+
private final MovieService movieService;
23+
24+
public MovieController(MovieService movieService) {
25+
this.movieService = movieService;
26+
}
27+
28+
@GetMapping("/graph")
29+
public Map<String, Object> graph(@RequestParam(value = "limit",required = false) Integer limit) {
30+
return movieService.graph(limit == null ? 100 : limit);
31+
}
32+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package movies.spring.data.neo4j.domain;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import org.neo4j.ogm.annotation.GeneratedValue;
7+
import org.neo4j.ogm.annotation.Id;
8+
import org.neo4j.ogm.annotation.NodeEntity;
9+
import org.neo4j.ogm.annotation.Relationship;
10+
11+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
12+
13+
/**
14+
* @author Mark Angrish
15+
*/
16+
@NodeEntity
17+
public class Movie {
18+
19+
@Id
20+
@GeneratedValue
21+
private Long id;
22+
private String title;
23+
private int released;
24+
private String tagline;
25+
26+
@JsonIgnoreProperties("movie")
27+
@Relationship(type = "ACTED_IN", direction = Relationship.INCOMING)
28+
private List<Role> roles;
29+
30+
public Movie() {
31+
}
32+
33+
public Movie(String title, int released, String tagline) {
34+
this.title = title;
35+
this.released = released;
36+
this.tagline = tagline;
37+
}
38+
39+
public Long getId() {
40+
return id;
41+
}
42+
43+
public String getTitle() {
44+
return title;
45+
}
46+
47+
public int getReleased() {
48+
return released;
49+
}
50+
51+
public String getTagline() {
52+
return tagline;
53+
}
54+
55+
public List<Role> getRoles() {
56+
return roles;
57+
}
58+
59+
public void addRole(Role role) {
60+
if (this.roles == null) {
61+
this.roles = new ArrayList<>();
62+
}
63+
this.roles.add(role);
64+
}
65+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package movies.spring.data.neo4j.domain;
2+
3+
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
8+
import org.neo4j.ogm.annotation.GeneratedValue;
9+
import org.neo4j.ogm.annotation.Id;
10+
import org.neo4j.ogm.annotation.NodeEntity;
11+
import org.neo4j.ogm.annotation.Relationship;
12+
13+
/**
14+
* @author Mark Angrish
15+
*/
16+
@NodeEntity
17+
public class Person {
18+
19+
@Id
20+
@GeneratedValue
21+
private Long id;
22+
private String name;
23+
private int born;
24+
25+
@Relationship(type = "ACTED_IN")
26+
private List<Movie> movies = new ArrayList<>();
27+
28+
public Person() {
29+
}
30+
31+
public Person(String name, int born) {
32+
this.name = name;
33+
this.born = born;
34+
}
35+
36+
public Long getId() {
37+
return id;
38+
}
39+
40+
public String getName() {
41+
return name;
42+
}
43+
44+
public int getBorn() {
45+
return born;
46+
}
47+
48+
public List<Movie> getMovies() {
49+
return movies;
50+
}
51+
}

0 commit comments

Comments
 (0)