@NodeEntity
public class Person {
@GraphId private Long nodeId;
private String name;
private String addr;
private int age;
@Relationship(type="WATCH")
private Set<Movie> movies;
}
@NodeEntity
public class Movie{
@GraphId private Long nodeId;
private String title;
private int released;
@Relationship(type="WATCH" ,direction = Relationship.INCOMING)
private Person person;
public Movie(){}
}
@RequestMapping(value = "/movieTest", method = RequestMethod.GET)
public Movie movieTest(){
Movie movie =movieRepository.findOne(5078L,1);
return movie;
}
public interface MovieRepository extends GraphRepository<Movie> {
}
I create a Person class and a Movie class ,Person "WATCH" Movie,Person has property "movies",and Movie has property "person",My purpose is to get Person by a movie id,but an "java.lang.StackOverflowError" exception happened when I call /movieTest API,because after findOne() executed , the result object movie has a sub-object person, and person has a sub-object movies ,then go to a endless loop, so what I wonder is how to deal this situation or what should I do when I need to get Person By a movie id?
Firstly we need to double check the model. In Cypher you are saying (:Person)-[:WATCH]->(:Movie)
. In your java code you are saying:
In general a movie could be watched by many people though right? If that's the case the movie class should hold a collection of people (with the same mapping).
If it's some sort of movie preview app where exactly 0..1
Person
s can watch a movie and once it's watched no one else can watch it (or it gets updated so the last person who watched it is the person) then you have several options:
You could add a custom query to your repository:
public interface PersonRepository extends GraphRepository<Person> {
@Query("MATCH (n:Person)-[r]->(m:Movie) WHERE ID(m) = {movieId} RETURN r")
Person findByMovieId(@Param("movieId) Long id);
}
Returning the relationship means your person object should get hydrated with the watched movie.
Simply retrieve the movie as you are with the findOne
method and then get the person from it: movie.getPerson()