Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why doesn't this work after my minor modification the movie class? #25

Closed
lingvisa opened this issue Feb 20, 2018 · 17 comments
Closed

Why doesn't this work after my minor modification the movie class? #25

lingvisa opened this issue Feb 20, 2018 · 17 comments

Comments

@lingvisa
Copy link

lingvisa commented Feb 20, 2018

If in the Movie class, I only keep a list of Persons without the Role list, and in the Person class, there is a list of Movie.
Person class:

@Relationship(type = "ACTED_IN")
	private List<Movie> movies = new ArrayList<>();

Movie class:

@Relationship(type = "ACTED_IN", direction = Relationship.INCOMING)
	private List<Person> actors = new ArrayList<>();

MovieRepository:

@RepositoryRestResource(collectionResourceRel = "movies", path = "movies")
public interface MovieRepository extends PagingAndSortingRepository<Movie, Long> {

	@Query("MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m LIMIT {limit}")
	Collection<Movie> graph(@Param("limit") int limit);
}

Why the "actors" is empty when I query the Movie repository? I have the following json output:

/ 20180219210651
// http://localhost:8080/graph?limit=1

[
  {
    "id": 155,
    "title": "The Birdcage",
    "released": 1996,
    "tagline": "Come as you are",
    "persons": [
      {
        "id": 140,
        "name": "Nathan Lane",
        "born": 1956,
        "movies": [
          155
        ]
      }
    ]
  }
]

I am using the query: "MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m, r, collect(a) LIMIT {limit}". How to output the relationship "ACTED_IN" in the json output? since that would be required in application. The output above only have Movie and the Persons associated with it.

@meistermeier
Copy link
Member

If you are using a custom query, there is no default depth of 1 used for the querying. It is the "plain" result of your query. Because you just return the Movie OGM / SDN do not get any information about the Person. I did not test it myself, but it should work if you additionally returncollect(p).

@lingvisa
Copy link
Author

You mean collect(m)? Where is the p?

@meistermeier
Copy link
Member

Oh, sorry, no I meant collect(a).

@lingvisa
Copy link
Author

collect(a) just gives more movies, but the actors[] are still all empty.

@lingvisa
Copy link
Author

Maybe because the Role has properties, I must use the RelatinoshipEntity? I just want to test something simpler. And I created another little graph for another domain without relationship property, but it ended up with the same thing. So I guess I am missing something. Maybe needs some setting somewhere.

@lingvisa
Copy link
Author

lingvisa commented Feb 20, 2018

I tested this "@query("MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m, r, collect(a) LIMIT {limit}")". The actors:[] are empty as well.

@lingvisa
Copy link
Author

Hi, meistermeier: Do you have a chance to take a look at this? If you change the List to List in the Movie class, then use @query("MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m, r, collect(a) LIMIT {limit}"), you will see the result. Thanks a lot.

@meistermeier
Copy link
Member

meistermeier commented Feb 21, 2018

It seems that (at least) a word is wrong here:

If you change the List to List in the Movie class

But I could reproduce the problem and you have to collect both relationship related "values". @Query("MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person) RETURN m, collect(r), collect(a) LIMIT {limit}") works.

(edit) I added a sample to my sdn playground project https://github.com/meistermeier/sdn-showcase/blob/d4f7b807735cae2239c5789bbbd1954805ffc5d9/src/test/java/com/meistermeier/neo4jsdn/sdnshowcase/CustomQueryTest.java

@lingvisa
Copy link
Author

lingvisa commented Feb 22, 2018

Hi, meistermeier: I put my version of the movie onto: https://github.com/lingvisa/test-movie.git and could you clone and have a test at why it still doesn't work? I followed your suggestion but still got empty results for the persons[]. The only change I made is to change to List in Movie, and then in the service/repository class I changed the return value to Collection movieRepository.graph(limit), since I don't want to see the original visualization, but only want to the see json output in Browser. I looked at your customquerytest example too. The query I used for testing is "http://localhost:8080/graph?limit=10".

@lingvisa
Copy link
Author

I tested in both the Movie project and the sdnshowcase project, in the unit test, the "collect(r), collect(a)" doesn't matter, whether collect is used, since the test is only relevant to the Movie or Person object, the first returned value. The unit test doesn't reveal anything about the issue when requesting through the restful service, the Collection is empty.

@meistermeier
Copy link
Member

Got it. Finally. Because you have the Role class in you class path OGM finds this class and put all the information into this relationship and skips evaluating the @Relationship annotations in the @NodeEntity classes because it has already found a matching relationship representation. After assembling the objects it "sets" the Role in Movie but unfortunately there is no field matching this type, so it does not get set.
So, your solution would be to remove the Role class, remove the @RelationshipEntity annotation or at least change the name of the relationship type in the annotation.

@lingvisa
Copy link
Author

lingvisa commented Feb 24, 2018

@meistermeier I updated my question above with my current json output. The output is almost what I want to see, except that it doesn't output the relationship "ACTED_IN". In json, I need to know what the relationship between Movie and Person. How to get that output too?

@meistermeier
Copy link
Member

The JSON does only get generated from the field names. So the only way is to add the annotation @JsonProperty("acted_in") or rename the field (and may be getters).

@lingvisa
Copy link
Author

Do you mean I need to define a new variable like "relation" in Movie and set the @JsonProperty annotation? If I add a new variable, the Movie's constructor has to be changed too. I guess I am not getting your point. In addition, most likely I also need to output the direction (Incoming/outcoming) together with the relationship name. I am thinking defining a new class to contain the relationship name and direction and then define this as an instance variable of the model class. But it seems awkward. What's the usual practice? I simply want the JSON object returned by the query contains the triples: Subject, Relation and Object. In this case, they are Movie, Acted_IN (incoming), and Persons.

@meistermeier
Copy link
Member

If it is just for the representation, you should add this annotation to your actors property in the Movie class.

@manavilai
Copy link

@lingvisa , did you get a chance to fix this..i have a similar issue when i query by personrepo.findByName(). It doesn't return the movies

@michael-simons
Copy link
Collaborator

Closing this as question. Feel free to discuss this on our community site.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants