├── .gitignore ├── src ├── main │ ├── java │ │ └── com │ │ │ └── comsysto │ │ │ └── neo4j │ │ │ └── showcase │ │ │ ├── model │ │ │ ├── RelationshipTypes.java │ │ │ ├── IdentifiableEntity.java │ │ │ ├── ClickedRelationship.java │ │ │ ├── RecommendRelationship.java │ │ │ ├── User.java │ │ │ └── Product.java │ │ │ ├── repository │ │ │ ├── UserRepository.java │ │ │ └── ProductRepository.java │ │ │ └── main │ │ │ ├── Main.java │ │ │ └── Neo4jPersister.java │ └── resources │ │ └── com │ │ └── comsysto │ │ └── neo4j │ │ └── showcase │ │ └── main │ │ └── related-to-via-test-context.xml └── test │ ├── resources │ └── com │ │ └── comsysto │ │ └── neo4j │ │ └── showcase │ │ └── related-to-via-test-context.xml │ └── java │ └── com │ └── comsysto │ └── neo4j │ └── showcase │ └── SpringDataNeo4jProductUserTest.java ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Intellij 2 | .idea/ 3 | *.iml 4 | *.iws 5 | 6 | # Mac 7 | .DS_Store 8 | .shell_history 9 | 10 | # Maven 11 | log/ 12 | target/ 13 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/RelationshipTypes.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | /** 4 | * @author: rkowalewski 5 | */ 6 | public final class RelationshipTypes { 7 | public static final String CLICKED = "CLICKED"; 8 | public static final String RECOMMEND = "RECOMMEND"; 9 | } 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spring Data Neo4j Showcase 2 | ======== 3 | 4 | Our Spring Data Neo4j showcase application for comSysto Blog Article Spring Data Neo4j (http://blog.comsysto.com/2013/07/10/spring-data-neo4j/). 5 | 6 | It uses Spring, Spring Data Neo4j and Maven to demonstrate how to recommend products based on other users' views. 7 | 8 | Please mail comments to Roger.Kowalewski@comsysto.com or Elisabeth.Engel@comsysto.com! 9 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.repository; 2 | 3 | import com.comsysto.neo4j.showcase.model.User; 4 | import org.springframework.data.neo4j.repository.GraphRepository; 5 | 6 | 7 | public interface UserRepository extends GraphRepository{ 8 | 9 | User findByUserId(String userId); 10 | 11 | Iterable findByUserNameLike(String userName); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/IdentifiableEntity.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | import org.springframework.data.neo4j.annotation.GraphId; 4 | 5 | /** 6 | * @author: rkowalewski 7 | */ 8 | public abstract class IdentifiableEntity { 9 | @GraphId 10 | private Long graphId; 11 | 12 | public Long getGraphId() { 13 | return graphId; 14 | } 15 | 16 | @Override 17 | public boolean equals( Object obj ) { 18 | return obj instanceof IdentifiableEntity && graphId.equals( ((IdentifiableEntity) obj).getGraphId() ); 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | return 0; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/main/Main.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.main; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | 5 | import javax.transaction.*; 6 | 7 | /** 8 | * @author: rkowalewski 9 | */ 10 | public class Main { 11 | 12 | private static final String CLASSPATH_LOCATION = "classpath:com/comsysto/neo4j/showcase/main/related-to-via-test-context.xml"; 13 | 14 | public static void main(String[] args) throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException { 15 | 16 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(CLASSPATH_LOCATION); 17 | 18 | Neo4jPersister neo4jPersister = (Neo4jPersister) context.getBean("neo4jPersister"); 19 | 20 | neo4jPersister.createTestData(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/com/comsysto/neo4j/showcase/related-to-via-test-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/resources/com/comsysto/neo4j/showcase/main/related-to-via-test-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.repository; 2 | 3 | import com.comsysto.neo4j.showcase.model.Product; 4 | import org.springframework.data.neo4j.annotation.Query; 5 | import org.springframework.data.neo4j.repository.GraphRepository; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.util.List; 9 | 10 | 11 | public interface ProductRepository extends GraphRepository { 12 | 13 | Product findByProductId(String productId); 14 | 15 | List findByProductNameLike(String productName); 16 | 17 | 18 | @Query("START product=node(*) " + 19 | "WHERE HAS (product.productName)" + 20 | "RETURN product " + 21 | "ORDER BY product.productName") 22 | List findAllProductsSortedByName(); 23 | 24 | 25 | @Query("START product=node:Product(productId={productId}) " + 26 | "MATCH product-[recommend:RECOMMEND]->otherProduct " + 27 | "RETURN otherProduct " + 28 | "ORDER BY recommend.count DESC " + 29 | "LIMIT 5 ") 30 | List findOtherUsersAlsoViewedProducts(@Param("productId") String productId); 31 | 32 | 33 | @Query("START product=node:Product(productId={productId}), user=node:User(userId={userId}) " + 34 | "MATCH product-[recommend:RECOMMEND]->otherProduct " + 35 | "WHERE not(user-[:CLICKED]->otherProduct) " + 36 | "RETURN otherProduct " + 37 | "ORDER BY recommend.count DESC " + 38 | "LIMIT 5 ") 39 | List findOtherUsersAlsoViewedProductsWithoutAlreadyViewed(@Param("productId") String productId, @Param("userId") String userId); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/ClickedRelationship.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | import org.springframework.data.neo4j.annotation.*; 4 | 5 | 6 | @RelationshipEntity(type = RelationshipTypes.CLICKED) 7 | public class ClickedRelationship 8 | { 9 | @GraphId 10 | private Long graphId; 11 | 12 | @StartNode 13 | @Fetch 14 | private User user; 15 | 16 | @EndNode 17 | @Fetch 18 | private Product product; 19 | 20 | private int count = 1; 21 | 22 | public ClickedRelationship() {/* NOOP */} 23 | 24 | public ClickedRelationship(User user, Product product) 25 | { 26 | this.user = user; 27 | this.product = product; 28 | } 29 | 30 | public User getUser() { 31 | return user; 32 | } 33 | 34 | public void setUser(User user) { 35 | this.user = user; 36 | } 37 | 38 | public Product getProduct() { 39 | return product; 40 | } 41 | 42 | public void setProduct(Product product) { 43 | this.product = product; 44 | } 45 | 46 | 47 | public int getCount() { 48 | return this.count; 49 | } 50 | 51 | public void setCount(int count) { 52 | this.count = count; 53 | } 54 | 55 | public void incrementCount () { 56 | this.count++; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) return true; 62 | if (o == null || getClass() != o.getClass()) return false; 63 | 64 | ClickedRelationship that = (ClickedRelationship) o; 65 | 66 | if (product != null ? !product.equals(that.product) : that.product != null) return false; 67 | if (user != null ? !user.equals(that.user) : that.user != null) return false; 68 | 69 | return true; 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | int result = 0; 75 | result = 31 * result + (user != null ? user.hashCode() : 0); 76 | result = 31 * result + (product != null ? product.hashCode() : 0); 77 | return result; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/RecommendRelationship.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | import org.springframework.data.neo4j.annotation.*; 4 | 5 | 6 | @RelationshipEntity(type = RelationshipTypes.RECOMMEND) 7 | public class RecommendRelationship 8 | { 9 | @GraphId 10 | private Long graphId; 11 | 12 | @StartNode 13 | @Fetch 14 | private Product productStart; 15 | 16 | @EndNode 17 | @Fetch 18 | private Product productEnd; 19 | 20 | private int count = 1; 21 | 22 | public RecommendRelationship() {/* NOOP */} 23 | 24 | public RecommendRelationship(Product productStart, Product productEnd) 25 | { 26 | this.productStart = productStart; 27 | this.productEnd = productEnd; 28 | } 29 | 30 | 31 | public Product getProductEnd() { 32 | return productEnd; 33 | } 34 | 35 | public void setProductEnd(Product productEnd) { 36 | this.productEnd = productEnd; 37 | } 38 | 39 | public Product getProductStart() { 40 | return productStart; 41 | } 42 | 43 | public void setProductStart(Product productStart) { 44 | this.productStart = productStart; 45 | } 46 | 47 | 48 | public int getCount() { 49 | return this.count; 50 | } 51 | 52 | public void setCount(int count) { 53 | this.count = count; 54 | } 55 | 56 | public void incrementCount () { 57 | this.count++; 58 | } 59 | 60 | @Override 61 | public boolean equals(Object o) { 62 | if (this == o) return true; 63 | if (o == null || getClass() != o.getClass()) return false; 64 | 65 | RecommendRelationship that = (RecommendRelationship) o; 66 | 67 | if (productEnd != null ? !productEnd.equals(that.productEnd) : that.productEnd != null) return false; 68 | if (productStart != null ? !productStart.equals(that.productStart) : that.productStart != null) return false; 69 | 70 | return true; 71 | } 72 | 73 | @Override 74 | public int hashCode() { 75 | int result = 0; 76 | result = 31 * result + (productStart != null ? productStart.hashCode() : 0); 77 | result = 31 * result + (productEnd != null ? productEnd.hashCode() : 0); 78 | return result; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/main/Neo4jPersister.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.main; 2 | 3 | import com.comsysto.neo4j.showcase.model.Product; 4 | import com.comsysto.neo4j.showcase.model.User; 5 | import com.comsysto.neo4j.showcase.repository.ProductRepository; 6 | import com.comsysto.neo4j.showcase.repository.UserRepository; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | /** 12 | * @author: rkowalewski 13 | */ 14 | @Component 15 | @Transactional 16 | public class Neo4jPersister { 17 | 18 | @Autowired 19 | public ProductRepository productRepository; 20 | @Autowired 21 | public UserRepository userRepository; 22 | 23 | private void userClickedProduct(User user, Product product) { 24 | 25 | user.addClickedProduct(product); 26 | 27 | userRepository.save(user); 28 | productRepository.save(product); 29 | } 30 | 31 | private Product createProduct(String id, String name) { 32 | return productRepository.save(new Product(id, name)); 33 | } 34 | 35 | private User createUser(String id, String name) { 36 | return userRepository.save(new User(id, name)); 37 | } 38 | 39 | public void createTestData() { 40 | User jordan = createUser("MJ", "Monika Jordan"); 41 | User pippen = createUser("SP", "Sandra Pippen"); 42 | User miller = createUser("JM", "John Miller"); 43 | 44 | Product pizzaMargarita = createProduct("Pizza_1", "Pizza Margarita"); 45 | Product pizzaFungi = createProduct("Pizza_2", "Pizza Fungi"); 46 | Product pizzaSalami = createProduct("Pizza_3", "Pizza Salami"); 47 | Product pizzaVegitarian = createProduct("Pizza_4", "Pizza Vegitarian"); 48 | Product pizzaRustica = createProduct("Pizza_5", "Pizza Rustica"); 49 | 50 | userClickedProduct(jordan, pizzaMargarita); 51 | userClickedProduct(jordan, pizzaFungi); 52 | userClickedProduct(jordan, pizzaSalami); 53 | 54 | userClickedProduct(pippen, pizzaMargarita); 55 | userClickedProduct(pippen, pizzaVegitarian); 56 | userClickedProduct(pippen, pizzaRustica); 57 | userClickedProduct(pippen, pizzaMargarita); 58 | userClickedProduct(pippen, pizzaVegitarian); 59 | 60 | userClickedProduct(miller, pizzaFungi); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/User.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | import org.springframework.data.neo4j.annotation.Indexed; 4 | import org.springframework.data.neo4j.annotation.NodeEntity; 5 | import org.springframework.data.neo4j.annotation.RelatedToVia; 6 | import org.springframework.data.neo4j.support.index.IndexType; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | @NodeEntity 12 | public class User extends IdentifiableEntity { 13 | 14 | @Indexed(unique = true) 15 | private String userId; 16 | 17 | @Indexed(indexType = IndexType.FULLTEXT, indexName = "userName") 18 | private String userName; 19 | 20 | private Product clickedBefore; 21 | 22 | @RelatedToVia(type = RelationshipTypes.CLICKED) 23 | private Set clickedProductsRelationships = new HashSet(); 24 | 25 | 26 | public User() {/* NOOP */} 27 | 28 | public User(String userId, String name) { 29 | super(); 30 | 31 | this.userId = userId; 32 | this.userName = name; 33 | } 34 | 35 | public String getUserId() { 36 | return userId; 37 | } 38 | 39 | public void setUserId(String userId) { 40 | this.userId = userId; 41 | } 42 | 43 | public String getUserName() { 44 | return userName; 45 | } 46 | 47 | public void setUserName(String userName) { 48 | this.userName = userName; 49 | } 50 | 51 | public Product getClickedBefore() { 52 | return clickedBefore; 53 | } 54 | 55 | public Set getAllClickedProducts() { 56 | Set clickedProducts = new HashSet(); 57 | 58 | for (ClickedRelationship clickedRelationship : this.clickedProductsRelationships) { 59 | clickedProducts.add(clickedRelationship.getProduct()); 60 | } 61 | 62 | return clickedProducts; 63 | } 64 | 65 | public Set getClickedProductsRelationships() { 66 | return clickedProductsRelationships; 67 | } 68 | 69 | public void addClickedProduct(Product clickedProduct) 70 | { 71 | ClickedRelationship clickedRelationship = new ClickedRelationship(this, clickedProduct); 72 | 73 | if (this.clickedBefore != null) { 74 | this.clickedBefore.addProductRecommend(clickedProduct); 75 | } 76 | 77 | if (this.clickedProductsRelationships.contains(clickedRelationship)) 78 | { 79 | for(ClickedRelationship clickRel : this.clickedProductsRelationships) { 80 | if (clickRel.getProduct().equals(clickedProduct)) { 81 | clickRel.incrementCount(); 82 | break; 83 | } 84 | } 85 | } 86 | else { 87 | this.clickedProductsRelationships.add(clickedRelationship); 88 | } 89 | 90 | this.clickedBefore = clickedProduct; 91 | 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | return "User{" + 97 | "graphId=" + this.getGraphId() + 98 | ", userId=" + this.userId + 99 | ", userName=" + this.userName + 100 | //", #clickedProductsRelationships=" + this.clickedProductsRelationships.size() + 101 | '}'; 102 | } 103 | 104 | @Override 105 | public boolean equals(Object o) { 106 | if (this == o) return true; 107 | if (o == null || getClass() != o.getClass()) return false; 108 | if (!super.equals(o)) return false; 109 | 110 | User user = (User) o; 111 | 112 | if (userId != null ? !userId.equals(user.userId) : user.userId != null) return false; 113 | 114 | return true; 115 | } 116 | 117 | @Override 118 | public int hashCode() { 119 | int result = super.hashCode(); 120 | result = 31 * result + (userId != null ? userId.hashCode() : 0); 121 | return result; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/comsysto/neo4j/showcase/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase.model; 2 | 3 | import org.springframework.data.neo4j.annotation.Indexed; 4 | import org.springframework.data.neo4j.annotation.NodeEntity; 5 | import org.springframework.data.neo4j.annotation.RelatedToVia; 6 | import org.springframework.data.neo4j.support.index.IndexType; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | @NodeEntity 12 | public class Product extends IdentifiableEntity { 13 | 14 | @Indexed(unique = true) 15 | private String productId; 16 | 17 | @Indexed(indexType = IndexType.FULLTEXT, indexName = "productName") 18 | private String productName; 19 | 20 | @RelatedToVia(type = RelationshipTypes.RECOMMEND) 21 | private Set productsRecommendRelationships = new HashSet(); 22 | 23 | 24 | public Product() {/* NOOP */} 25 | 26 | public Product(String productId, String productName) { 27 | super(); 28 | 29 | this.productId = productId; 30 | this.productName = productName; 31 | 32 | } 33 | 34 | public String getProductId() { 35 | return productId; 36 | } 37 | 38 | public void setProductId(String productId) { 39 | this.productId = productId; 40 | } 41 | 42 | public String getProductName() { 43 | return productName; 44 | } 45 | 46 | public void setProductName(String productName) { 47 | this.productName = productName; 48 | } 49 | 50 | public Set getProductsRecommendRelationships() { 51 | return productsRecommendRelationships; 52 | } 53 | 54 | public Set getAllProductsRecommendations() { 55 | 56 | Set recommendProducts = new HashSet(); 57 | 58 | for (RecommendRelationship recommendRelationship : this.productsRecommendRelationships) { 59 | recommendProducts.add(recommendRelationship.getProductEnd()); 60 | } 61 | 62 | return recommendProducts; 63 | } 64 | 65 | public void setProductsRecommendRelationships(Set productsRecommendRelationships) { 66 | this.productsRecommendRelationships = productsRecommendRelationships; 67 | } 68 | 69 | public void addProductRecommend(Product productRecommend) 70 | { 71 | RecommendRelationship recommendRelationship = new RecommendRelationship(this, productRecommend); 72 | 73 | if (this.productsRecommendRelationships.contains(recommendRelationship)) 74 | { 75 | for(RecommendRelationship recommendRel : this.productsRecommendRelationships) { 76 | if (recommendRel.getProductEnd().equals(productRecommend)) { 77 | recommendRel.incrementCount(); 78 | break; 79 | } 80 | } 81 | } 82 | else { 83 | productsRecommendRelationships.add(recommendRelationship); 84 | } 85 | } 86 | 87 | 88 | @Override 89 | public String toString() { 90 | return "Product{" + 91 | "graphId=" + this.getGraphId() + 92 | ", productId=" + productId + 93 | ", productName=" + productName + 94 | //", #productsRecommendRelationships=" + productsRecommendRelationships.size() + 95 | //", #userClicked=" + usersClicked.size() + 96 | '}'; 97 | } 98 | 99 | 100 | @Override 101 | public boolean equals(Object o) { 102 | if (this == o) return true; 103 | if (o == null || getClass() != o.getClass()) return false; 104 | if (!super.equals(o)) return false; 105 | 106 | Product product = (Product) o; 107 | 108 | if (productId != null ? !productId.equals(product.productId) : product.productId != null) return false; 109 | 110 | return true; 111 | } 112 | 113 | @Override 114 | public int hashCode() { 115 | int result = super.hashCode(); 116 | result = 31 * result + (productId != null ? productId.hashCode() : 0); 117 | return result; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-data-neo4j-showcase 8 | spring-data-neo4j-showcase 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 2.2.0.RELEASE 13 | 1.9 14 | 3.2.1.RELEASE 15 | 1.9.M04 16 | 17 | 18 | 19 | 20 | org.springframework 21 | spring-core 22 | ${spring.core.version} 23 | 24 | 25 | 26 | org.springframework.data 27 | spring-data-neo4j 28 | ${spring.data.neo4j.version} 29 | 30 | 31 | 32 | org.neo4j 33 | neo4j 34 | ${neo4j.kernel.version} 35 | 36 | 37 | 38 | org.neo4j 39 | neo4j-cypher 40 | ${neo4j.kernel.version} 41 | 42 | 43 | 44 | org.neo4j 45 | neo4j-cypher-dsl 46 | ${neo4j.cypher.dsl.version} 47 | 48 | 49 | 50 | org.neo4j 51 | neo4j-kernel 52 | ${neo4j.kernel.version} 53 | test-jar 54 | 55 | 56 | 57 | junit 58 | junit 59 | 4.11 60 | 61 | 62 | org.springframework 63 | spring-test 64 | ${spring.core.version} 65 | 66 | 67 | 68 | cglib 69 | cglib 70 | 2.2.2 71 | 72 | 73 | 74 | javax.validation 75 | validation-api 76 | 1.1.0.Final 77 | 78 | 79 | 80 | 81 | 82 | org.springframework.maven.release 83 | Spring Maven Release Repository 84 | http://maven.springsource.org/release 85 | 86 | true 87 | 88 | false 89 | 90 | 91 | neo4j-public-release-repository 92 | http://m2.neo4j.org/releases 93 | 94 | false 95 | 96 | 97 | true 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | maven-compiler-plugin 106 | 107 | 1.6 108 | 1.6 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/test/java/com/comsysto/neo4j/showcase/SpringDataNeo4jProductUserTest.java: -------------------------------------------------------------------------------- 1 | package com.comsysto.neo4j.showcase; 2 | 3 | import com.comsysto.neo4j.showcase.model.Product; 4 | import com.comsysto.neo4j.showcase.model.User; 5 | import com.comsysto.neo4j.showcase.repository.ProductRepository; 6 | import com.comsysto.neo4j.showcase.repository.UserRepository; 7 | import org.junit.After; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.neo4j.graphdb.GraphDatabaseService; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.data.neo4j.support.node.Neo4jHelper; 14 | import org.springframework.test.annotation.Rollback; 15 | import org.springframework.test.context.ContextConfiguration; 16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 17 | import org.springframework.transaction.annotation.Transactional; 18 | 19 | import java.util.List; 20 | import java.util.Set; 21 | 22 | import static org.junit.Assert.assertEquals; 23 | import static org.junit.Assert.assertTrue; 24 | 25 | 26 | @RunWith(SpringJUnit4ClassRunner.class) 27 | @ContextConfiguration(locations = {"classpath:com/comsysto/neo4j/showcase/related-to-via-test-context.xml"}) 28 | @Transactional 29 | public class SpringDataNeo4jProductUserTest { 30 | 31 | @Autowired 32 | private ProductRepository productRepository; 33 | 34 | @Autowired 35 | private UserRepository userRepository; 36 | 37 | @Autowired 38 | GraphDatabaseService graphDatabaseService; 39 | 40 | User jordan, pippen, miller; 41 | Product pizzaMargarita, pizzaFungi, pizzaSalami, pizzaVegitarian, pizzaRustica; 42 | 43 | @Before 44 | public void createSzenario () { 45 | 46 | jordan = createUser("MJ", "Monika Jordan"); 47 | pippen = createUser("SP", "Sandra Pippen"); 48 | miller = createUser("JM", "John Miller"); 49 | 50 | pizzaMargarita = createProduct("Pizza_1", "Pizza Margarita"); 51 | pizzaFungi = createProduct("Pizza_2", "Pizza Fungi"); 52 | pizzaSalami = createProduct("Pizza_3", "Pizza Salami"); 53 | pizzaVegitarian = createProduct("Pizza_4", "Pizza Vegitarian"); 54 | pizzaRustica = createProduct("Pizza_5", "Pizza Rustica"); 55 | 56 | userClickedProduct(jordan, pizzaMargarita); 57 | userClickedProduct(jordan, pizzaFungi); 58 | userClickedProduct(jordan, pizzaSalami); 59 | 60 | userClickedProduct(pippen, pizzaMargarita); 61 | userClickedProduct(pippen, pizzaVegitarian); 62 | userClickedProduct(pippen, pizzaRustica); 63 | userClickedProduct(pippen, pizzaMargarita); 64 | userClickedProduct(pippen, pizzaVegitarian); 65 | 66 | userClickedProduct(miller, pizzaFungi); 67 | } 68 | 69 | @Test 70 | public void testProducts() { 71 | 72 | //Load and check relations 73 | List allProducts = productRepository.findAll().as(List.class); 74 | assertEquals("there should be five products in the products repository", 5, allProducts.size()); 75 | 76 | assertTrue("saved and loaded products should be equal", 77 | allProducts.contains(pizzaMargarita) && allProducts.contains(pizzaFungi) && 78 | allProducts.contains(pizzaSalami) && allProducts.contains(pizzaVegitarian) && 79 | allProducts.contains(pizzaRustica)); 80 | 81 | } 82 | 83 | @Test 84 | public void testProductsSortedByName() { 85 | 86 | //Load and check relations 87 | List allProducts = productRepository.findAllProductsSortedByName(); 88 | assertEquals("there should be five products in the products repository", 5, allProducts.size()); 89 | 90 | assertTrue("saved and loaded products should be equal", 91 | allProducts.contains(pizzaMargarita) && allProducts.contains(pizzaFungi) && 92 | allProducts.contains(pizzaSalami) && allProducts.contains(pizzaVegitarian) && 93 | allProducts.contains(pizzaRustica)); 94 | 95 | assertTrue("first product should be fungi in sorted order", allProducts.get(0).equals(pizzaFungi)); 96 | 97 | assertTrue("last product should be vegiatrian in sorted order", allProducts.get(allProducts.size()-1).equals(pizzaVegitarian)); 98 | } 99 | 100 | @Test 101 | public void testUsers() { 102 | 103 | List allUsers = userRepository.findAll().as(List.class); 104 | assertEquals("there should be three users in the user repository", 3, allUsers.size()); 105 | 106 | Set clickedProducts = allUsers.get(0).getAllClickedProducts(); 107 | assertEquals("Monika Jordan should have three clicked products", 3, clickedProducts.size()); 108 | assertTrue("The two products Monika Jordan clicked on should be pizza margarita and pizza fungi", 109 | clickedProducts.contains(pizzaMargarita) && clickedProducts.contains(pizzaFungi) && clickedProducts.contains(pizzaSalami)); 110 | } 111 | 112 | @Test 113 | public void testfindOtherUsersAlsoViewedProductsCypherQuery() { 114 | 115 | List alsoViewedProducts = productRepository.findOtherUsersAlsoViewedProducts(pizzaMargarita.getProductId()); 116 | assertEquals("there should be two products recommended", 2, alsoViewedProducts.size()); 117 | assertTrue("using this cypher query should return a list with also viewed products", 118 | alsoViewedProducts.contains(pizzaFungi) && alsoViewedProducts.contains(pizzaVegitarian)); 119 | } 120 | @Test 121 | public void testfindOtherUsersAlsoViewedProductsWithoutAlreadyViewedCypherQuery() { 122 | 123 | List alsoViewedProductsWithoutAlreadyViewed = productRepository.findOtherUsersAlsoViewedProductsWithoutAlreadyViewed(pizzaMargarita.getProductId(), miller.getUserId()); 124 | assertEquals("there should be one product recommended", 1, alsoViewedProductsWithoutAlreadyViewed.size()); 125 | assertTrue("using this cypher query should return a list with also viewed products without the ones Miller already viewed", 126 | alsoViewedProductsWithoutAlreadyViewed.contains(pizzaVegitarian)); 127 | 128 | } 129 | 130 | private Product createProduct(String id, String name) { 131 | return productRepository.save(new Product(id, name)); 132 | } 133 | 134 | private User createUser(String id, String name) { 135 | return userRepository.save(new User(id, name)); 136 | } 137 | 138 | private void userClickedProduct(User user, Product product) { 139 | 140 | user.addClickedProduct(product); 141 | 142 | userRepository.save(user); 143 | productRepository.save(product); 144 | } 145 | 146 | @After 147 | public void cleanDB() { 148 | Neo4jHelper.cleanDb(graphDatabaseService); 149 | } 150 | } 151 | --------------------------------------------------------------------------------