From d453ccd08433e7ef1c09b017d32901960d8df244 Mon Sep 17 00:00:00 2001 From: Michael Hunger Date: Sat, 5 Nov 2011 09:29:26 +0100 Subject: [PATCH] added non-aj cineasts example renamed all cineasts examples in pom.xml --- .../cineasts-aspects/pom.xml | 4 +- .../cineasts-rest/pom.xml | 4 +- .../cineasts/.gitignore | 12 +++ spring-data-neo4j-examples/cineasts/pom.xml | 19 ++--- .../cineasts/controller/MovieController.java | 11 ++- .../java/org/neo4j/cineasts/domain/Movie.java | 30 +++++-- .../org/neo4j/cineasts/domain/Person.java | 33 ++++++-- .../org/neo4j/cineasts/domain/Rating.java | 25 ++++-- .../java/org/neo4j/cineasts/domain/Role.java | 19 +++++ .../java/org/neo4j/cineasts/domain/User.java | 39 ++++++--- .../movieimport/MovieDbImportService.java | 23 +++--- .../cineasts/repository/MovieRepository.java | 3 +- .../cineasts/repository/PersonRepository.java | 3 +- .../cineasts/repository/UserRepository.java | 3 +- .../cineasts/service/DatabasePopulator.java | 25 +++--- .../service/FriendsMovieRecommendations.java | 74 ----------------- .../service/MovieRecommendations.java | 82 ------------------- .../service/Neo4jDatabaseCleaner.java | 14 ++-- .../org/neo4j/cineasts/domain/DomainTest.java | 27 +++--- .../service/MoviesRepositoryTest.java | 42 +++++----- 20 files changed, 221 insertions(+), 271 deletions(-) create mode 100644 spring-data-neo4j-examples/cineasts/.gitignore delete mode 100644 spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java delete mode 100644 spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java diff --git a/spring-data-neo4j-examples/cineasts-aspects/pom.xml b/spring-data-neo4j-examples/cineasts-aspects/pom.xml index 6210c014e..4c366c464 100644 --- a/spring-data-neo4j-examples/cineasts-aspects/pom.xml +++ b/spring-data-neo4j-examples/cineasts-aspects/pom.xml @@ -3,11 +3,11 @@ 4.0.0 org.neo4j.examples - movies-aspects + cineasts-aspects 2.0-SNAPSHOT war - Movies + Cineasts.net Aspects UTF-8 diff --git a/spring-data-neo4j-examples/cineasts-rest/pom.xml b/spring-data-neo4j-examples/cineasts-rest/pom.xml index 5ecf50177..a29285f9c 100644 --- a/spring-data-neo4j-examples/cineasts-rest/pom.xml +++ b/spring-data-neo4j-examples/cineasts-rest/pom.xml @@ -3,11 +3,11 @@ 4.0.0 org.neo4j - movies-rest + cineasts-rest 2.0-SNAPSHOT war - Movies over REST + Cineasts over REST UTF-8 diff --git a/spring-data-neo4j-examples/cineasts/.gitignore b/spring-data-neo4j-examples/cineasts/.gitignore new file mode 100644 index 000000000..490bd87be --- /dev/null +++ b/spring-data-neo4j-examples/cineasts/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +*.ipr +*.iws +*.iml +*.zip +data +target +*.log +tmp +.classpath +.project +.settings diff --git a/spring-data-neo4j-examples/cineasts/pom.xml b/spring-data-neo4j-examples/cineasts/pom.xml index c3b54477b..604f38d00 100644 --- a/spring-data-neo4j-examples/cineasts/pom.xml +++ b/spring-data-neo4j-examples/cineasts/pom.xml @@ -7,7 +7,7 @@ 2.0-SNAPSHOT war - Movies + Cineasts.net UTF-8 @@ -16,7 +16,6 @@ UTF-8 1.5.M02 2.0.0.BUILD-SNAPSHOT - 1.6.12.M1 1.6.1 @@ -176,7 +175,7 @@ org.springframework.data - spring-data-neo4j-aspects + spring-data-neo4j ${spring-data-graph.version} @@ -222,11 +221,11 @@ 1.7.2 - + cglib @@ -234,12 +233,6 @@ 2.2 - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - 1.0.0.Final - - @@ -318,7 +311,7 @@ - + diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java index ddfa15478..b61cd3954 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/controller/MovieController.java @@ -6,7 +6,7 @@ import org.neo4j.cineasts.domain.Rating; import org.neo4j.cineasts.domain.User; import org.neo4j.cineasts.repository.MovieRepository; import org.neo4j.cineasts.repository.PersonRepository; -import org.neo4j.cineasts.service.CineastsRepository; +import org.neo4j.cineasts.repository.UserRepository; import org.neo4j.cineasts.service.CineastsUserDetailsService; import org.neo4j.cineasts.service.DatabasePopulator; import org.neo4j.helpers.collection.IteratorUtil; @@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -34,8 +35,12 @@ public class MovieController { @Autowired private PersonRepository personRepository; @Autowired + private UserRepository userRepository; + @Autowired private CineastsUserDetailsService userDetailsService; @Autowired + Neo4jOperations template; + @Autowired private DatabasePopulator populator; private static final Logger log = LoggerFactory.getLogger(MovieController.class); @@ -61,7 +66,7 @@ public class MovieController { final int stars = movie.getStars(); model.addAttribute("stars", stars); Rating rating = null; - if (user!=null) rating = movie.getRelationshipTo(user, Rating.class, "RATED"); + if (user!=null) rating = template.getRelationshipBetween(movie, user, Rating.class, "RATED"); if (rating == null) rating = new Rating().rate(stars,null); model.addAttribute("userRating",rating); } @@ -75,7 +80,7 @@ public class MovieController { if (user != null && movie != null) { int stars1 = stars==null ? -1 : stars; String comment1 = comment!=null ? comment.trim() : null; - user.rate(movie, stars1, comment1); + user.rate(template,movie, stars1, comment1); } return singleMovieView(model,movieId); } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java index fdad46ad6..c7e4f4fe0 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Movie.java @@ -1,11 +1,7 @@ package org.neo4j.cineasts.domain; -import org.neo4j.graphdb.Direction; import org.neo4j.helpers.collection.IteratorUtil; -import org.springframework.data.neo4j.annotation.NodeEntity; -import org.springframework.data.neo4j.annotation.RelatedTo; -import org.springframework.data.neo4j.annotation.RelatedToVia; -import org.springframework.data.neo4j.annotation.Indexed; +import org.springframework.data.neo4j.annotation.*; import org.springframework.data.neo4j.support.index.IndexType; import java.util.*; @@ -19,6 +15,7 @@ import static org.neo4j.graphdb.Direction.INCOMING; */ @NodeEntity public class Movie { + @GraphId Long nodeId; @Indexed String id; @@ -34,11 +31,11 @@ public class Movie { @RelatedTo(type = "ACTS_IN", direction = INCOMING) Set actors; - @RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING) + @RelatedToVia(type = "ACTS_IN", direction = INCOMING) Iterable roles; - @RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING) - Iterable ratings; + @RelatedToVia(type = "RATED", direction = INCOMING) + @Fetch Iterable ratings; private String language; private String imdbId; private String tagline; @@ -224,5 +221,22 @@ public class Movie { int numberOfParts = parts.length; return numberOfParts > 0 ? parts[numberOfParts-1] : null; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Movie movie = (Movie) o; + if (nodeId == null) return super.equals(o); + return nodeId.equals(movie.nodeId); + + } + + @Override + public int hashCode() { + return nodeId != null ? nodeId.hashCode() : super.hashCode(); + } + } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java index 9cb5e9698..f2df05154 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Person.java @@ -1,12 +1,11 @@ package org.neo4j.cineasts.domain; -import org.springframework.data.neo4j.annotation.Indexed; -import org.springframework.data.neo4j.annotation.NodeEntity; -import org.springframework.data.neo4j.annotation.RelatedTo; -import org.springframework.data.neo4j.annotation.RelatedToVia; +import org.springframework.data.neo4j.annotation.*; import org.springframework.data.neo4j.support.index.IndexType; +import org.springframework.data.neo4j.template.Neo4jOperations; import java.util.Date; +import java.util.HashSet; import java.util.Set; /** @@ -15,6 +14,7 @@ import java.util.Set; */ @NodeEntity public class Person { + @GraphId Long nodeId; @Indexed String id; @Indexed(indexType=IndexType.FULLTEXT, indexName = "people") @@ -100,7 +100,7 @@ public class Person { } @RelatedTo(elementClass = Movie.class, type = "DIRECTED") - private Set directedMovies; + private Set directedMovies=new HashSet(); public Set getDirectedMovies() { return directedMovies; @@ -117,10 +117,27 @@ public class Person { return roles; } - public Role playedIn(Movie movie, String roleName) { - Role role = relateTo(movie, Role.class, "ACTS_IN"); + public Role playedIn(Neo4jOperations template,Movie movie, String roleName) { + Role role = template.createRelationshipBetween(this, movie, Role.class, "ACTS_IN",false); role.setName(roleName); - return role; + return template.save(role); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Person person = (Person) o; + if (nodeId == null) return super.equals(o); + return nodeId.equals(person.nodeId); + + } + + @Override + public int hashCode() { + return nodeId != null ? nodeId.hashCode() : super.hashCode(); + } + + } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java index ea14ea5f9..7ccd2eda7 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Rating.java @@ -1,8 +1,6 @@ package org.neo4j.cineasts.domain; -import org.springframework.data.neo4j.annotation.EndNode; -import org.springframework.data.neo4j.annotation.RelationshipEntity; -import org.springframework.data.neo4j.annotation.StartNode; +import org.springframework.data.neo4j.annotation.*; /** * @author mh @@ -12,9 +10,9 @@ import org.springframework.data.neo4j.annotation.StartNode; public class Rating { private static final int MAX_STARS = 5; private static final int MIN_STARS = 0; + @GraphId Long id; - @StartNode - User user; + @StartNode User user; @EndNode Movie movie; int stars; @@ -49,4 +47,21 @@ public class Rating { if (comment!=null && !comment.isEmpty()) this.comment = comment; return this; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Rating rating = (Rating) o; + if (id == null) return super.equals(o); + return id.equals(rating.id); + + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : super.hashCode(); + } + } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java index e5a4dac27..97f84680d 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/Role.java @@ -1,6 +1,7 @@ package org.neo4j.cineasts.domain; import org.springframework.data.neo4j.annotation.EndNode; +import org.springframework.data.neo4j.annotation.GraphId; import org.springframework.data.neo4j.annotation.RelationshipEntity; import org.springframework.data.neo4j.annotation.StartNode; @@ -10,6 +11,7 @@ import org.springframework.data.neo4j.annotation.StartNode; */ @RelationshipEntity public class Role { + @GraphId Long id; @EndNode Movie movie; @StartNode Person actor; @@ -35,4 +37,21 @@ public class Role { public String toString() { return String.format("%s acts as %s in %s", actor, name, movie); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Role role = (Role) o; + if (id == null) return super.equals(o); + return id.equals(role.id); + + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : super.hashCode(); + } + } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java index 8d362207a..bb14020fb 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/domain/User.java @@ -2,10 +2,8 @@ package org.neo4j.cineasts.domain; import org.neo4j.graphdb.Direction; import org.neo4j.helpers.collection.IteratorUtil; -import org.springframework.data.neo4j.annotation.Indexed; -import org.springframework.data.neo4j.annotation.NodeEntity; -import org.springframework.data.neo4j.annotation.RelatedTo; -import org.springframework.data.neo4j.annotation.RelatedToVia; +import org.springframework.data.neo4j.annotation.*; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.security.authentication.encoding.Md5PasswordEncoder; import org.springframework.security.core.GrantedAuthority; @@ -14,6 +12,8 @@ import java.util.Set; @NodeEntity public class User { + @GraphId Long nodeId; + private static final String SALT = "cewuiqwzie"; public static final String FRIEND = "FRIEND"; public static final String RATED = "RATED"; @@ -38,22 +38,23 @@ public class User { return new Md5PasswordEncoder().encodePassword(password, SALT); } - @RelatedToVia(elementClass = Rating.class, type = RATED) - Iterable ratings; + @RelatedToVia(type = RATED) + @Fetch Iterable ratings; - @RelatedTo(elementClass = Movie.class, type = RATED) + @RelatedTo(type = RATED) Set favorites; - @RelatedTo(elementClass = User.class, type = FRIEND, direction = Direction.BOTH) - Set friends; + @RelatedTo(type = FRIEND, direction = Direction.BOTH) + @Fetch Set friends; public void addFriend(User friend) { this.friends.add(friend); } - public Rating rate(Movie movie, int stars, String comment) { - return relateTo(movie, Rating.class, RATED).rate(stars, comment); + public Rating rate(Neo4jOperations template, Movie movie, int stars, String comment) { + final Rating rating = template.createRelationshipBetween(this, movie, Rating.class, RATED, false).rate(stars, comment); + return template.save(rating); } public Collection getRatings() { @@ -114,4 +115,20 @@ public class User { return name(); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + User user = (User) o; + if (nodeId == null) return super.equals(o); + return nodeId.equals(user.nodeId); + + } + + @Override + public int hashCode() { + return nodeId != null ? nodeId.hashCode() : super.hashCode(); + } } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java index 6f8250c96..17b707d16 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/movieimport/MovieDbImportService.java @@ -1,12 +1,14 @@ package org.neo4j.cineasts.movieimport; -import org.neo4j.cineasts.domain.*; +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.Person; +import org.neo4j.cineasts.domain.Roles; import org.neo4j.cineasts.repository.MovieRepository; import org.neo4j.cineasts.repository.PersonRepository; -import org.neo4j.cineasts.service.CineastsRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -21,15 +23,16 @@ public class MovieDbImportService { MovieDbJsonMapper movieDbJsonMapper = new MovieDbJsonMapper(); @Autowired - MovieRepository movieRepository; + private MovieRepository movieRepository; @Autowired - PersonRepository personRepository; + private PersonRepository personRepository; @Autowired - MovieDbApiClient client; + private MovieDbApiClient client; @Autowired - MovieDbLocalStorage localStorage; + private MovieDbLocalStorage localStorage; + @Autowired private Neo4jOperations template; @Transactional public Map importMovies(Map ranges) { @@ -68,7 +71,7 @@ public class MovieDbImportService { Map data = loadMovieData(movieId); if (data.containsKey("not_found")) throw new RuntimeException("Data for Movie "+movieId+" not found."); movieDbJsonMapper.mapToMovie(data, movie); - movie.persist(); + movieRepository.save(movie); relatePersonsToMovie(movie, data); return movie; } @@ -84,7 +87,7 @@ public class MovieDbImportService { } private void relatePersonsToMovie(Movie movie, Map data) { - Collection cast = (Collection) data.get("cast"); + @SuppressWarnings("unchecked") Collection cast = (Collection) data.get("cast"); for (Map entry : cast) { String id = "" + entry.get("id"); String jobName = (String) entry.get("job"); @@ -99,7 +102,7 @@ public class MovieDbImportService { person.directed(movie); break; case ACTS_IN: - person.playedIn(movie, (String) entry.get("character")); + person.playedIn(template,movie, (String) entry.get("character")); break; } } @@ -118,7 +121,7 @@ public class MovieDbImportService { if (data.containsKey("not_found")) throw new RuntimeException("Data for Person "+personId+" not found."); Person newPerson=new Person(personId,null); movieDbJsonMapper.mapToPerson(data, newPerson); - return newPerson.persist(); + return personRepository.save(newPerson); } private Map loadPersonData(String personId) { diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java index 824479306..ab06de3af 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/MovieRepository.java @@ -8,6 +8,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.repository.GraphRepository; import org.springframework.data.neo4j.repository.NamedIndexRepository; +import org.springframework.data.neo4j.repository.RelationshipOperationsRepository; import java.util.List; @@ -15,7 +16,7 @@ import java.util.List; * @author mh * @since 02.04.11 */ -public interface MovieRepository extends GraphRepository, NamedIndexRepository { +public interface MovieRepository extends GraphRepository, NamedIndexRepository, RelationshipOperationsRepository { Movie findById(String id); Page findByTitleLike(String title, Pageable page); diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java index 65fbc3b2c..c3c91bb48 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/PersonRepository.java @@ -2,11 +2,12 @@ package org.neo4j.cineasts.repository; import org.neo4j.cineasts.domain.Person; import org.springframework.data.neo4j.repository.GraphRepository; +import org.springframework.data.neo4j.repository.RelationshipOperationsRepository; /** * @author mh * @since 02.04.11 */ -public interface PersonRepository extends GraphRepository { +public interface PersonRepository extends GraphRepository, RelationshipOperationsRepository { Person findById(String id); } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java index d879532be..16ea3b9db 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/repository/UserRepository.java @@ -2,10 +2,11 @@ package org.neo4j.cineasts.repository; import org.neo4j.cineasts.domain.User; import org.springframework.data.neo4j.repository.GraphRepository; +import org.springframework.data.neo4j.repository.RelationshipOperationsRepository; /** * @author mh * @since 02.04.11 */ -public interface UserRepository extends GraphRepository { +public interface UserRepository extends GraphRepository, RelationshipOperationsRepository { } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java index 00740c8b1..b2220a50b 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/DatabasePopulator.java @@ -1,13 +1,14 @@ package org.neo4j.cineasts.service; -import org.neo4j.cineasts.repository.MovieRepository; -import org.neo4j.kernel.AbstractGraphDatabase; -import org.neo4j.cineasts.domain.*; +import org.neo4j.cineasts.domain.Movie; +import org.neo4j.cineasts.domain.User; import org.neo4j.cineasts.movieimport.MovieDbImportService; +import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.cineasts.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,10 +24,9 @@ import static java.util.Arrays.asList; @Service public class DatabasePopulator { - @Autowired - Neo4jTemplate ctx; - @Autowired - MovieRepository movieRepository; + @Autowired UserRepository userRepository; + @Autowired MovieRepository movieRepository; + @Autowired Neo4jOperations template; @Autowired MovieDbImportService importService; @@ -34,8 +34,8 @@ public class DatabasePopulator { @Transactional public List populateDatabase() { - User me = new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER).persist(); - User ollie = new User("ollie", "Olliver", "password",User.Roles.ROLE_USER).persist(); + User me = userRepository.save(new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER)); + User ollie = userRepository.save(new User("ollie", "Olliver", "password",User.Roles.ROLE_USER)); me.addFriend(ollie); List ids = asList(19995 , 194, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 13, 20526, 11, 1893, 1892, 1894, 168, 193, 200, 157, 152, 201, 154, 12155, 58, 285, 118, 22, 392, 5255, 568, 9800, 497, 101, 120, 121, 122); List result=new ArrayList(ids.size()); @@ -44,12 +44,13 @@ public class DatabasePopulator { } //me.rate(repository.getMovie("13"),5,"Inspiring"); - me.rate(movieRepository.findById("603"),5,"Best of the series"); + final Movie movie = movieRepository.findById("603"); + me.rate(template, movie,5,"Best of the series"); return result; } @Transactional public void cleanDb() { - new Neo4jDatabaseCleaner((AbstractGraphDatabase) ctx.getGraphDatabaseService()).cleanDb(); + new Neo4jDatabaseCleaner(template).cleanDb(); } } diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java deleted file mode 100644 index 9f63b5b01..000000000 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/FriendsMovieRecommendations.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.neo4j.cineasts.service; - -import org.neo4j.cineasts.domain.Movie; -import org.neo4j.cineasts.domain.Rating; -import org.neo4j.cineasts.domain.User; -import org.neo4j.graphdb.traversal.Evaluators; -import org.neo4j.graphdb.traversal.TraversalDescription; -import org.neo4j.kernel.Traversal; -import org.neo4j.kernel.Uniqueness; -import org.springframework.data.neo4j.core.EntityPath; - -import java.util.HashMap; -import java.util.Map; - -import static org.neo4j.graphdb.DynamicRelationshipType.withName; - -/** - * @author mh - * @since 04.04.11 - */ -public class FriendsMovieRecommendations { - private final Map ratings = new HashMap(); - private final int ratingDistance; - - public static class MovieRating { - int stars; - int count; - public void update(Rating rating, int weight) { - this.stars += rating.getStars()*weight; - this.count += weight; - } - public int average() { - return count == 0 ? 0 : stars / count; - } - public String toString() { - return String.valueOf(average()); - } - - } - public FriendsMovieRecommendations(int ratingDistance) { - this.ratingDistance = ratingDistance; - } - - public Map getRecommendationsFor(User user) { - TraversalDescription traversal = Traversal.description().breadthFirst() - .uniqueness(Uniqueness.NODE_GLOBAL).relationships(withName(User.FRIEND)) - .evaluator(Evaluators.toDepth(ratingDistance)).evaluator(Evaluators.excludeStartPosition()); - - Iterable result = user.findAllPathsByTraversal(traversal); - Iterable> friends = (Iterable>)result; - for (EntityPath path : friends) { - int weight = ratingDistance - path.length(); - User friend = path.endEntity(); - aggregateRatings(friend,weight); - } - for (Rating rating : user.getRatings()) { - ratings.remove(rating.getMovie()); - } - return ratings; - } - - private void aggregateRatings(User friend, int weight) { - for (Rating rating : friend.getRatings()) { - obtainRating(rating.getMovie()).update(rating, weight); - } - } - - private MovieRating obtainRating(Movie movie) { - if (!ratings.containsKey(movie)) { - ratings.put(movie, new MovieRating()); - } - return ratings.get(movie); - } -} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java deleted file mode 100644 index ac262f5de..000000000 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/MovieRecommendations.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.neo4j.cineasts.service; - -import org.neo4j.cineasts.domain.Movie; -import org.neo4j.cineasts.domain.User; -import org.neo4j.cineasts.repository.MovieRepository; -import org.neo4j.graphdb.Path; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.traversal.Evaluation; -import org.neo4j.graphdb.traversal.Evaluator; -import org.neo4j.graphdb.traversal.TraversalDescription; -import org.neo4j.kernel.Traversal; -import org.neo4j.kernel.Uniqueness; - -import java.util.HashMap; -import java.util.Map; - -import static org.neo4j.graphdb.Direction.OUTGOING; -import static org.neo4j.graphdb.DynamicRelationshipType.withName; - -/** -* @author mh -* @since 04.04.11 -*/ -class MovieRecommendations implements Evaluator { - private final Map ratings=new HashMap(); - private final int ratingDistance; - private MovieRepository movieRepository; - - public MovieRecommendations(MovieRepository movieRepository, int ratingDistance) { - this.movieRepository = movieRepository; - this.ratingDistance = ratingDistance; - } - - public Map getRecommendationsFor(User user) { - TraversalDescription traversal= Traversal.description().breadthFirst() - .uniqueness(Uniqueness.NODE_PATH) - .relationships(withName(User.FRIEND)) - .relationships(withName(User.RATED), OUTGOING) - .evaluator(this); - return averageRecommendations(user, traversal); - } - - private Map averageRecommendations(User user, TraversalDescription traversal) { // todo sort, limit - Map result=new HashMap(); - for (Movie movie : movieRepository.findAllByTraversal(user, traversal)) { - final int[] rating = ratings.get(movie.getNodeId()); - result.put(movie, rating[1]==0 ? 0 : rating[0]/rating[1]); - } - return result; - } - - @Override - public Evaluation evaluate(Path path) { - final int distance = path.length() - 1; - if (distance > ratingDistance) return Evaluation.EXCLUDE_AND_PRUNE; - Relationship rated = path.lastRelationship(); - if (rated != null && rated.getType().name().equals(User.RATED)) { - if (distance == 0) return Evaluation.EXCLUDE_AND_PRUNE; // my rated movies - updateRating(rated, distance); - return Evaluation.INCLUDE_AND_PRUNE; - } - System.out.println(); - return Evaluation.EXCLUDE_AND_CONTINUE; - } - - private void updateRating(Relationship rated, int distance) { - final long movieId = rated.getEndNode().getId(); - int[] rating = obtainRating(movieId); - - int weight = ratingDistance - distance; - final Integer stars = (Integer) rated.getProperty("stars", 0); - rating[0] += weight * stars; - rating[1] += weight; - } - - private int[] obtainRating(long movieId) { - if (!ratings.containsKey(movieId)) { - ratings.put(movieId,new int[2]); - } - return ratings.get(movieId); - } -} diff --git a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java index 15d995459..f82a7838c 100644 --- a/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java +++ b/spring-data-neo4j-examples/cineasts/src/main/java/org/neo4j/cineasts/service/Neo4jDatabaseCleaner.java @@ -1,11 +1,9 @@ package org.neo4j.cineasts.service; -import org.neo4j.graphdb.Direction; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.Transaction; +import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.IndexManager; -import org.neo4j.kernel.AbstractGraphDatabase; +import org.springframework.data.neo4j.support.DelegatingGraphDatabase; +import org.springframework.data.neo4j.template.Neo4jOperations; import java.util.Arrays; import java.util.HashMap; @@ -16,10 +14,10 @@ import java.util.Map; * @since 02.03.11 */ public class Neo4jDatabaseCleaner { - private AbstractGraphDatabase graph; + private GraphDatabaseService graph; - public Neo4jDatabaseCleaner(AbstractGraphDatabase graph) { - this.graph = graph; + public Neo4jDatabaseCleaner(Neo4jOperations template) { + this.graph = ((DelegatingGraphDatabase)template.getGraphDatabase()).getGraphDatabaseService(); } public Map cleanDb() { diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java index 114ec458c..c24c9b71c 100644 --- a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/domain/DomainTest.java @@ -4,8 +4,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.cineasts.repository.PersonRepository; import org.neo4j.cineasts.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @@ -30,18 +32,21 @@ public class DomainTest { @Autowired protected UserRepository userRepository; + @Autowired Neo4jOperations template; + @Autowired PersonRepository personRepository; + @Before public void setUp() throws Exception { } @Test public void actorCanPlayARoleInAMovie() { - Person tomHanks = new Person("1","Tom Hanks").persist(); - Movie forestGump = new Movie("1", "Forrest Gump").persist(); + Person tomHanks = template.save(new Person("1", "Tom Hanks")); + Movie forestGump = template.save(new Movie("1", "Forrest Gump")); - Role role = tomHanks.playedIn(forestGump, "Forrest"); + Role role = tomHanks.playedIn(template, forestGump, "Forrest"); - Movie foundForestGump = this.movieRepository.findByPropertyValue(null, "id", "1"); + Movie foundForestGump = this.movieRepository.findById("1"); assertEquals("created and looked up movie equal", forestGump, foundForestGump); Role firstRole = foundForestGump.getRoles().iterator().next(); @@ -51,7 +56,7 @@ public class DomainTest { @Test public void canFindMovieByTitleQuery() { - Movie forestGump = new Movie("1", "Forrest Gump").persist(); + Movie forestGump = template.save(new Movie("1", "Forrest Gump")); Iterator queryResults = movieRepository.findAllByQuery("search", "title", "Forre*").iterator(); assertTrue("found movie by query",queryResults.hasNext()); Movie foundMovie = queryResults.next(); @@ -61,12 +66,12 @@ public class DomainTest { @Test public void userCanRateMovie() { - Movie movie= new Movie("1","Forrest Gump").persist(); - User user = new User("ich","Micha","password").persist(); - Rating awesome = user.rate(movie, 5, "Awesome"); + Movie movie = template.save(new Movie("1", "Forrest Gump")); + User user = template.save(new User("ich", "Micha", "password")); + Rating awesome = user.rate(template, movie, 5, "Awesome"); - - User foundUser = userRepository.findByPropertyValue("login", "ich"); + user = userRepository.findByPropertyValue("login", "ich"); + movie = movieRepository.findById("1"); Rating rating = user.getRatings().iterator().next(); assertEquals(awesome,rating); assertEquals("Awesome",rating.getComment()); @@ -75,7 +80,7 @@ public class DomainTest { } @Test public void canFindUserByLogin() { - User user = new User("ich","Micha","password").persist(); + User user = template.save(new User("ich", "Micha", "password")); User foundUser = userRepository.findByPropertyValue("login", "ich"); assertEquals(user, foundUser); } diff --git a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java index 9f7b27851..afa33231c 100644 --- a/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java +++ b/spring-data-neo4j-examples/cineasts/src/test/java/org/neo4j/cineasts/service/MoviesRepositoryTest.java @@ -7,9 +7,11 @@ import org.neo4j.cineasts.domain.MovieRecommendation; import org.neo4j.cineasts.domain.Rating; import org.neo4j.cineasts.domain.User; import org.neo4j.cineasts.repository.MovieRepository; +import org.neo4j.cineasts.repository.UserRepository; import org.neo4j.helpers.collection.IteratorUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; +import org.springframework.data.neo4j.template.Neo4jOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @@ -29,25 +31,26 @@ import static org.junit.Assert.assertTrue; @ContextConfiguration({"/movies-test-context.xml"}) @Transactional public class MoviesRepositoryTest { - @Autowired - MovieRepository movieRepository; + @Autowired MovieRepository movieRepository; + @Autowired UserRepository userRepository; + @Autowired Neo4jOperations template; @Test public void testGetMovie() throws Exception { - Movie movie = new Movie("1", "Test-Movie").persist(); + Movie movie = movieRepository.save(new Movie("1", "Test-Movie")); Movie found = movieRepository.findById("1"); assertEquals("movie found by id", movie, found); } @Test public void testGetMovieRecommendations() throws Exception { - Movie movie = new Movie("1", "Test-Movie").persist(); - Movie movie2 = new Movie("2", "Test-Movie2").persist(); - User user=new User("me","me","me").persist(); - user.rate(movie,3,"me"); - User friend=new User("friend","friend","friend").persist(); - friend.rate(movie,5,"friend"); - friend.rate(movie2,3,"friend2"); + Movie movie = movieRepository.save(new Movie("1", "Test-Movie")); + Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2")); + User user = userRepository.save(new User("me", "me", "me")); + user.rate(template,movie,3,"me"); + User friend = userRepository.save(new User("friend", "friend", "friend")); + friend.rate(template, movie, 5, "friend"); + friend.rate(template, movie2, 3, "friend2"); assertEquals(2,movieRepository.count()); final List recommendations = movieRepository.getRecommendations(user); assertEquals("one recommendation", 1, recommendations.size()); @@ -56,9 +59,10 @@ public class MoviesRepositoryTest { } @Test public void testRateMovie() throws Exception { - Movie movie = new Movie("1", "Test-Movie").persist(); - User user=new User("me","me","me").persist(); - user.rate(movie, 5, "comment"); + Movie movie = movieRepository.save(new Movie("1", "Test-Movie")); + User user = userRepository.save(new User("me", "me", "me")); + user.rate(template, movie, 5, "comment"); + movie = movieRepository.findById("1"); final Rating rating = IteratorUtil.first(movie.getRatings()); assertEquals("rating stars", 5, rating.getStars()); assertEquals("rating comment", "comment", rating.getComment()); @@ -68,9 +72,9 @@ public class MoviesRepositoryTest { @Test public void testFindTwoMovies() throws Exception { - Movie movie1 = new Movie("1", "Test-Movie1").persist(); - Movie movie2 = new Movie("2", "Test-Movie2").persist(); - Movie movie3 = new Movie("3", "Another-Movie3").persist(); + Movie movie1 = movieRepository.save(new Movie("1", "Test-Movie1")); + Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2")); + Movie movie3 = movieRepository.save(new Movie("3", "Another-Movie3")); List found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 2)).getContent(); assertEquals("2 movies found", 2, found.size()); assertEquals("2 correct movies found by query", new HashSet(asList(movie1, movie2)), new HashSet(found)); @@ -78,9 +82,9 @@ public class MoviesRepositoryTest { @Test public void testFindTwoMoviesButRestrictToOne() throws Exception { - Movie movie1 = new Movie("1", "Test-Movie1").persist(); - Movie movie2 = new Movie("2", "Test-Movie2").persist(); - Movie movie3 = new Movie("3", "Another-Movie3").persist(); + Movie movie1 = movieRepository.save(new Movie("1", "Test-Movie1")); + Movie movie2 = movieRepository.save(new Movie("2", "Test-Movie2")); + Movie movie3 = movieRepository.save(new Movie("3", "Another-Movie3")); List found = movieRepository.findByTitleLike("Test*", new PageRequest(0, 1)).getContent(); assertEquals("1 movie found",1,found.size()); assertTrue("1 correct movie found by query", found.get(0).getTitle().startsWith("Test"));