8. Repositories

Serving a good cause

We wanted to add repositories with domain-specific operations. Interestingly there was support for a very advanced repository infrastructure. You just declare an entity specific repository interface and get all commonly used methods for free without implementing any of boilerplate code.

So we started by creating a movie-related repository, simply by creating an empty interface.

Example 8.1. Movie repository

package org.neo4j.cineasts.repository;
public interface MovieRepository extends GraphRepository<Movie> {}


Then we enabled repository support in the Spring context configuration by simply adding:

Example 8.2. Repository context configuration

<neo4j:repositories base-package="org.neo4j.cineasts.repository"/>


Besides the existing repository operations (like CRUD, and many standard queries) it was possible to declare custom methods, which we explored later. Those methods' names could be more domain centric and expressive than the generic operations. For simple use-cases like finding by id's this is good enough. So we first let Spring autowire our MovieController with the MovieRepository. That way we could perform simple persistence operations.

Example 8.3. Usage of a repository

@Autowired MovieRepository repo;
...
  Movie movie = repo.findByPropertyValue("id",movieId);


We went on exploring the repository infrastructure. A very cool feature was something that we so far only heard about from Grails developers. Deriving queries from method names. Impressive! So we had a more explicit method for the id lookup.

Example 8.4. Derived movie-repository query method

public interface MovieRepository extends GraphRepository<Movie> {
  Movie getMovieById(String id);
}


In our wildest dreams we imagined the method names we would come up with, and what kinds of queries those could generate. But some, more complex queries would be cumbersome to read and write. So in those cases it is better to just annotate the finder method. We did this much later, and just wanted to give you a peek into the future. There is much more, you can do with repositories, it is worthwhile to explore.

Example 8.5. Annotated movie-repository query method

public interface MovieRepository extends GraphRepository<Movie> {
 @Query("start user=node:User({0}) match user-[r:RATED]->movie return movie order by r.stars desc limit 10")
 Iterable<Movie> getTopRatedMovies(User uer);
}