Bael 6625 new (#14476)
* BAEL-6625 - spring data neo4j example * BAEL-6625 - spring data neo4j example * BAEL-6625 - optimized imports * BAEL-6625 - moving project to jdk9 and above * BAEL-6625 - changing test names
This commit is contained in:
		
							parent
							
								
									65ee0b068e
								
							
						
					
					
						commit
						0323955992
					
				| @ -1,178 +0,0 @@ | ||||
| package com.baeldung.neo4j; | ||||
| 
 | ||||
| 
 | ||||
| import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.time.Duration; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.junit.After; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.neo4j.configuration.GraphDatabaseSettings; | ||||
| import org.neo4j.dbms.api.DatabaseManagementService; | ||||
| import org.neo4j.dbms.api.DatabaseManagementServiceBuilder; | ||||
| import org.neo4j.graphdb.GraphDatabaseService; | ||||
| import org.neo4j.graphdb.Label; | ||||
| import org.neo4j.graphdb.Node; | ||||
| import org.neo4j.graphdb.NotFoundException; | ||||
| import org.neo4j.graphdb.RelationshipType; | ||||
| import org.neo4j.graphdb.Result; | ||||
| import org.neo4j.graphdb.Transaction; | ||||
| 
 | ||||
| /** | ||||
|  * To run this test you will need to have an instance of the docker running on your machine (Docker desktop - for Windows and Docker instance for linux) | ||||
|  * After your docker instance is up run this test | ||||
|  */ | ||||
| public class Neo4jLiveTest { | ||||
| 
 | ||||
|     private static GraphDatabaseService graphDb; | ||||
|     private static Transaction transaction; | ||||
|     private static DatabaseManagementService managementService; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() { | ||||
|         managementService = new DatabaseManagementServiceBuilder(new File("data/cars").toPath()) | ||||
|                 .setConfig( GraphDatabaseSettings.transaction_timeout, Duration.ofSeconds( 60 ) ) | ||||
|                 .setConfig( GraphDatabaseSettings.preallocate_logical_logs, false ).build(); | ||||
|         graphDb = managementService.database( DEFAULT_DATABASE_NAME ); | ||||
|     } | ||||
| 
 | ||||
|     @After | ||||
|     public void tearDown() { | ||||
|         managementService.shutdown(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testPersonCar() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         Node car = transaction.createNode(Label.label("Car")); | ||||
|         car.setProperty("make", "tesla"); | ||||
|         car.setProperty("model", "model3"); | ||||
| 
 | ||||
|         Node owner = transaction.createNode(Label.label("Person")); | ||||
|         owner.setProperty("firstName", "baeldung"); | ||||
|         owner.setProperty("lastName", "baeldung"); | ||||
| 
 | ||||
|         owner.createRelationshipTo(car, RelationshipType.withName("owner")); | ||||
| 
 | ||||
|         Result result = transaction.execute("MATCH (c:Car) <-[owner]- (p:Person) " + | ||||
|                 "WHERE c.make = 'tesla'" + | ||||
|                 "RETURN p.firstName, p.lastName"); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
| 
 | ||||
|         Assert.assertEquals("baeldung", firstResult.get("p.firstName")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCreateNode() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" + | ||||
|                 "RETURN baeldung"); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
|         Node firstNode = (Node) firstResult.get("baeldung"); | ||||
| 
 | ||||
|         Assert.assertEquals(firstNode.getProperty("name"), "Baeldung"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCreateNodeAndLink() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||
|                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||
|                 "RETURN baeldung, tesla"); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
| 
 | ||||
|         Assert.assertTrue(firstResult.containsKey("baeldung")); | ||||
|         Assert.assertTrue(firstResult.containsKey("tesla")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testFindAndReturn() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||
|                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||
|                 "RETURN baeldung, tesla"); | ||||
| 
 | ||||
|         Result result = transaction.execute("MATCH (company:Company)-[:owns]-> (car:Car)" + | ||||
|                 "WHERE car.make='tesla' and car.model='modelX'" + | ||||
|                 "RETURN company.name"); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
| 
 | ||||
|         Assert.assertEquals(firstResult.get("company.name"), "Baeldung"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testUpdate() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||
|                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||
|                 "RETURN baeldung, tesla"); | ||||
| 
 | ||||
|         Result result = transaction.execute("MATCH (car:Car)" + | ||||
|                 "WHERE car.make='tesla'" + | ||||
|                 " SET car.milage=120" + | ||||
|                 " SET car :Car:Electro" + | ||||
|                 " SET car.model=NULL" + | ||||
|                 " RETURN car"); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
|         Node car = (Node) firstResult.get("car"); | ||||
| 
 | ||||
|         Assert.assertEquals(car.getProperty("milage"), 120L); | ||||
|         Assert.assertEquals(car.getLabels(), Arrays.asList(Label.label("Car"), Label.label("Electro"))); | ||||
| 
 | ||||
|         try { | ||||
|             car.getProperty("model"); | ||||
|             Assert.fail(); | ||||
|         } catch (NotFoundException e) { | ||||
|             // expected | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testDelete() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||
|                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||
|                 "RETURN baeldung, tesla"); | ||||
| 
 | ||||
|         transaction.execute("MATCH (company:Company)" + | ||||
|                 " WHERE company.name='Baeldung'" + | ||||
|                 " DELETE company"); | ||||
| 
 | ||||
|         Result result = transaction.execute("MATCH (company:Company)" + | ||||
|                 " WHERE company.name='Baeldung'" + | ||||
|                 " RETURN company"); | ||||
| 
 | ||||
|         Assert.assertFalse(result.hasNext()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testBindings() { | ||||
|         transaction = graphDb.beginTx(); | ||||
|         Map<String, Object> params = new HashMap<>(); | ||||
|         params.put("name", "baeldung"); | ||||
|         params.put("make", "tesla"); | ||||
|         params.put("model", "modelS"); | ||||
| 
 | ||||
|         Result result = transaction.execute("CREATE (baeldung:Company {name:$name}) " + | ||||
|                 "-[:owns]-> (tesla:Car {make: $make, model: $model})" + | ||||
|                 "RETURN baeldung, tesla", params); | ||||
| 
 | ||||
|         Map<String, Object> firstResult = result.next(); | ||||
|         Assert.assertTrue(firstResult.containsKey("baeldung")); | ||||
|         Assert.assertTrue(firstResult.containsKey("tesla")); | ||||
| 
 | ||||
|         Node car = (Node) firstResult.get("tesla"); | ||||
|         Assert.assertEquals(car.getProperty("model"), "modelS"); | ||||
|     } | ||||
| } | ||||
| @ -15,53 +15,39 @@ | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.neo4j</groupId> | ||||
|             <artifactId>neo4j-ogm-embedded-driver</artifactId> | ||||
|             <version>${neo4j-ogm.version}</version> | ||||
|             <groupId>org.neo4j.test</groupId> | ||||
|             <artifactId>neo4j-harness</artifactId> | ||||
|             <version>${neo4j-harness.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.data</groupId> | ||||
|             <artifactId>spring-data-neo4j</artifactId> | ||||
|             <version>${spring-data-neo4j.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.voodoodyne.jackson.jsog</groupId> | ||||
|             <artifactId>jackson-jsog</artifactId> | ||||
|             <version>${jackson-jsog.version}</version> | ||||
|             <scope>compile</scope> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-data-neo4j</artifactId> | ||||
|             <version>${spring-boot.version}</version> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <groupId>org.springframework.boot</groupId> | ||||
|                     <artifactId>spring-boot-starter-logging</artifactId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <version>${spring-boot.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.neo4j</groupId> | ||||
|             <artifactId>neo4j-ogm-test</artifactId> | ||||
|             <version>${neo4j-ogm.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.neo4j.test</groupId> | ||||
|             <artifactId>neo4j-harness</artifactId> | ||||
|             <version>${neo4j.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework</groupId> | ||||
|             <artifactId>spring-test</artifactId> | ||||
|             <version>${spring-test.version}</version> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <groupId>org.springframework.boot</groupId> | ||||
|                     <artifactId>spring-boot-starter-logging</artifactId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <properties> | ||||
|         <neo4j.version>3.4.6</neo4j.version> | ||||
|         <spring-data-neo4j.version>5.0.1.RELEASE</spring-data-neo4j.version> | ||||
|         <jackson-jsog.version>1.1</jackson-jsog.version> | ||||
|         <spring-boot.version>2.0.1.RELEASE</spring-boot.version> | ||||
|         <spring-test.version>5.0.1.RELEASE</spring-test.version> | ||||
|         <neo4j-ogm.version>3.1.2</neo4j-ogm.version> | ||||
|         <spring-boot.version>2.7.14</spring-boot.version> | ||||
|         <neo4j-harness.version>5.10.0</neo4j-harness.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,12 @@ | ||||
| package com.baeldung.spring.data.neo4j; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class Neo4JApplication { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(Neo4JApplication.class, args); | ||||
|     } | ||||
| } | ||||
| @ -1,26 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.config; | ||||
| 
 | ||||
| import org.neo4j.ogm.config.Configuration.Builder; | ||||
| import org.neo4j.ogm.session.SessionFactory; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; | ||||
| 
 | ||||
| @ComponentScan(basePackages = { "com.baeldung.spring.data.neo4j.services" }) | ||||
| @Configuration | ||||
| @EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repository") | ||||
| public class MovieDatabaseNeo4jConfiguration { | ||||
| 
 | ||||
|     public static final String URL = System.getenv("NEO4J_URL") != null ? System.getenv("NEO4J_URL") : "http://neo4j:movies@localhost:7474"; | ||||
| 
 | ||||
|     @Bean | ||||
|     public org.neo4j.ogm.config.Configuration getConfiguration() { | ||||
|     	return new Builder().uri(URL).build(); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public SessionFactory getSessionFactory() { | ||||
|         return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain"); | ||||
|     } | ||||
| } | ||||
| @ -1,36 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.config; | ||||
| 
 | ||||
| import org.neo4j.ogm.config.Configuration.Builder; | ||||
| import org.neo4j.ogm.session.SessionFactory; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.Profile; | ||||
| import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; | ||||
| import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableTransactionManagement | ||||
| @ComponentScan(basePackages = { "com.baeldung.spring.data.neo4j.services" }) | ||||
| @EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repository") | ||||
| @Profile({ "embedded", "test" }) | ||||
| public class MovieDatabaseNeo4jTestConfiguration { | ||||
| 
 | ||||
|     @Bean | ||||
|     public org.neo4j.ogm.config.Configuration getConfiguration() { | ||||
|     	org.neo4j.ogm.config.Configuration config = new Builder().build(); | ||||
|         return config; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public SessionFactory getSessionFactory() { | ||||
|         return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain"); | ||||
|     } | ||||
|      | ||||
|     @Bean | ||||
|     public Neo4jTransactionManager transactionManager() { | ||||
|         return new Neo4jTransactionManager(getSessionFactory()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.spring.data.neo4j.config; | ||||
| 
 | ||||
| import org.neo4j.cypherdsl.core.renderer.Dialect; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| 
 | ||||
| @Configuration | ||||
| public class Neo4jConfig { | ||||
|     @Bean | ||||
|     org.neo4j.cypherdsl.core.renderer.Configuration cypherDslConfiguration() { | ||||
|         return org.neo4j.cypherdsl.core.renderer.Configuration.newConfig() | ||||
|                 .withDialect(Dialect.NEO4J_5).build(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,48 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| 
 | ||||
| import org.springframework.data.neo4j.core.schema.Id; | ||||
| import org.springframework.data.neo4j.core.schema.Node; | ||||
| import org.springframework.data.neo4j.core.schema.Relationship; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Node("Author") | ||||
| public class Author { | ||||
|     @Id | ||||
|     private Long id; | ||||
| 
 | ||||
|     private String name; | ||||
| 
 | ||||
|     @Relationship(type = "WRITTEN_BY", direction = Relationship.Direction.INCOMING) | ||||
|     private List<Book> books; | ||||
| 
 | ||||
|     public Author(Long id, String name) { | ||||
|         this.id = id; | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public Long getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
|     public void setId(Long id) { | ||||
|         this.id = id; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public List<Book> getBooks() { | ||||
|         return books; | ||||
|     } | ||||
| 
 | ||||
|     public void setBooks(List<Book> books) { | ||||
|         this.books = books; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,58 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import org.springframework.data.neo4j.core.schema.Id; | ||||
| import org.springframework.data.neo4j.core.schema.Node; | ||||
| import org.springframework.data.neo4j.core.schema.Property; | ||||
| import org.springframework.data.neo4j.core.schema.Relationship; | ||||
| 
 | ||||
| @Node("Book") | ||||
| public class Book { | ||||
|     @Id | ||||
|     private String isbn; | ||||
| 
 | ||||
|     @Property("name") | ||||
|     private String title; | ||||
| 
 | ||||
|     private Integer year; | ||||
| 
 | ||||
|     @Relationship(type = "WRITTEN_BY", direction = Relationship.Direction.OUTGOING) | ||||
|     private Author author; | ||||
| 
 | ||||
|     public Book(String isbn, String title, Integer year) { | ||||
|         this.isbn = isbn; | ||||
|         this.title = title; | ||||
|         this.year = year; | ||||
|     } | ||||
| 
 | ||||
|     public String getIsbn() { | ||||
|         return isbn; | ||||
|     } | ||||
| 
 | ||||
|     public void setIsbn(String isbn) { | ||||
|         this.isbn = isbn; | ||||
|     } | ||||
| 
 | ||||
|     public String getTitle() { | ||||
|         return title; | ||||
|     } | ||||
| 
 | ||||
|     public void setTitle(String title) { | ||||
|         this.title = title; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getYear() { | ||||
|         return year; | ||||
|     } | ||||
| 
 | ||||
|     public void setYear(Integer year) { | ||||
|         this.year = year; | ||||
|     } | ||||
| 
 | ||||
|     public Author getAuthor() { | ||||
|         return author; | ||||
|     } | ||||
| 
 | ||||
|     public void setAuthor(Author author) { | ||||
|         this.author = author; | ||||
|     } | ||||
| } | ||||
| @ -1,48 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import org.neo4j.ogm.annotation.GeneratedValue; | ||||
| import org.neo4j.ogm.annotation.Id; | ||||
| import org.neo4j.ogm.annotation.NodeEntity; | ||||
| import org.neo4j.ogm.annotation.Relationship; | ||||
| 
 | ||||
| @NodeEntity | ||||
| public class Car { | ||||
|     @Id @GeneratedValue | ||||
|     private Long id; | ||||
| 
 | ||||
|     private String make; | ||||
| 
 | ||||
|     @Relationship(direction = "INCOMING") | ||||
|     private Company company; | ||||
| 
 | ||||
|     public Car(String make, String model) { | ||||
|         this.make = make; | ||||
|         this.model = model; | ||||
|     } | ||||
| 
 | ||||
|     public Long getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
|     public void setId(Long id) { | ||||
|         this.id = id; | ||||
|     } | ||||
| 
 | ||||
|     public String getMake() { | ||||
|         return make; | ||||
|     } | ||||
| 
 | ||||
|     public void setMake(String make) { | ||||
|         this.make = make; | ||||
|     } | ||||
| 
 | ||||
|     public String getModel() { | ||||
|         return model; | ||||
|     } | ||||
| 
 | ||||
|     public void setModel(String model) { | ||||
|         this.model = model; | ||||
|     } | ||||
| 
 | ||||
|     private String model; | ||||
| } | ||||
| @ -1,42 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import org.neo4j.ogm.annotation.NodeEntity; | ||||
| import org.neo4j.ogm.annotation.Relationship; | ||||
| 
 | ||||
| @NodeEntity | ||||
| public class Company { | ||||
|     private Long id; | ||||
| 
 | ||||
|     private String name; | ||||
| 
 | ||||
|     @Relationship(type="owns") | ||||
|     private Car car; | ||||
| 
 | ||||
|     public Company(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public Long getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
|     public void setId(Long id) { | ||||
|         this.id = id; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public Car getCar() { | ||||
|         return car; | ||||
|     } | ||||
| 
 | ||||
|     public void setCar(Car car) { | ||||
|         this.car = car; | ||||
|     } | ||||
| } | ||||
| @ -1,64 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonIdentityInfo; | ||||
| import com.voodoodyne.jackson.jsog.JSOGGenerator; | ||||
| 
 | ||||
| import org.neo4j.ogm.annotation.GeneratedValue; | ||||
| import org.neo4j.ogm.annotation.Id; | ||||
| import org.neo4j.ogm.annotation.NodeEntity; | ||||
| import org.neo4j.ogm.annotation.Relationship; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @JsonIdentityInfo(generator = JSOGGenerator.class) | ||||
| 
 | ||||
| @NodeEntity | ||||
| public class Movie { | ||||
|     @Id @GeneratedValue | ||||
|     Long id; | ||||
| 
 | ||||
|     private String title; | ||||
| 
 | ||||
|     private int released; | ||||
|     private String tagline; | ||||
| 
 | ||||
|     @Relationship(type = "ACTED_IN", direction = Relationship.INCOMING) | ||||
|     private List<Role> roles; | ||||
| 
 | ||||
|     public Movie() { | ||||
|     } | ||||
| 
 | ||||
|     public String getTitle() { | ||||
|         return title; | ||||
|     } | ||||
| 
 | ||||
|     public int getReleased() { | ||||
|         return released; | ||||
|     } | ||||
| 
 | ||||
|     public String getTagline() { | ||||
|         return tagline; | ||||
|     } | ||||
| 
 | ||||
|     public Collection<Role> getRoles() { | ||||
|         return roles; | ||||
|     } | ||||
| 
 | ||||
|     public void setTitle(String title) { | ||||
|         this.title = title; | ||||
|     } | ||||
| 
 | ||||
|     public void setReleased(int released) { | ||||
|         this.released = released; | ||||
|     } | ||||
| 
 | ||||
|     public void setTagline(String tagline) { | ||||
|         this.tagline = tagline; | ||||
|     } | ||||
| 
 | ||||
|     public void setRoles(List<Role> roles) { | ||||
|         this.roles = roles; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,52 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonIdentityInfo; | ||||
| import com.voodoodyne.jackson.jsog.JSOGGenerator; | ||||
| 
 | ||||
| import org.neo4j.ogm.annotation.GeneratedValue; | ||||
| import org.neo4j.ogm.annotation.Id; | ||||
| import org.neo4j.ogm.annotation.NodeEntity; | ||||
| import org.neo4j.ogm.annotation.Relationship; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @JsonIdentityInfo(generator = JSOGGenerator.class) | ||||
| @NodeEntity | ||||
| public class Person { | ||||
|     @Id @GeneratedValue | ||||
|     Long id; | ||||
| 
 | ||||
|     private String name; | ||||
|     private int born; | ||||
| 
 | ||||
|     @Relationship(type = "ACTED_IN") | ||||
|     private List<Movie> movies; | ||||
| 
 | ||||
|     public Person() { | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public int getBorn() { | ||||
|         return born; | ||||
|     } | ||||
| 
 | ||||
|     public List<Movie> getMovies() { | ||||
|         return movies; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public void setBorn(int born) { | ||||
|         this.born = born; | ||||
|     } | ||||
| 
 | ||||
|     public void setMovies(List<Movie> movies) { | ||||
|         this.movies = movies; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,50 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.domain; | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonIdentityInfo; | ||||
| import com.voodoodyne.jackson.jsog.JSOGGenerator; | ||||
| import org.neo4j.ogm.annotation.EndNode; | ||||
| import org.neo4j.ogm.annotation.GeneratedValue; | ||||
| import org.neo4j.ogm.annotation.Id; | ||||
| import org.neo4j.ogm.annotation.RelationshipEntity; | ||||
| import org.neo4j.ogm.annotation.StartNode; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| @JsonIdentityInfo(generator = JSOGGenerator.class) | ||||
| @RelationshipEntity(type = "ACTED_IN") | ||||
| public class Role { | ||||
|     @Id @GeneratedValue | ||||
| 	Long id; | ||||
|     private Collection<String> roles; | ||||
|     @StartNode | ||||
|     private Person person; | ||||
|     @EndNode | ||||
|     private Movie movie; | ||||
| 
 | ||||
|     public Role() { | ||||
|     } | ||||
| 
 | ||||
|     public Collection<String> getRoles() { | ||||
|         return roles; | ||||
|     } | ||||
| 
 | ||||
|     public Person getPerson() { | ||||
|         return person; | ||||
|     } | ||||
| 
 | ||||
|     public Movie getMovie() { | ||||
|         return movie; | ||||
|     } | ||||
| 
 | ||||
|     public void setRoles(Collection<String> roles) { | ||||
|         this.roles = roles; | ||||
|     } | ||||
| 
 | ||||
|     public void setPerson(Person person) { | ||||
|         this.person = person; | ||||
|     } | ||||
| 
 | ||||
|     public void setMovie(Movie movie) { | ||||
|         this.movie = movie; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,16 @@ | ||||
| package com.baeldung.spring.data.neo4j.repository; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.domain.Author; | ||||
| import com.baeldung.spring.data.neo4j.domain.Book; | ||||
| import org.springframework.data.neo4j.repository.Neo4jRepository; | ||||
| import org.springframework.data.neo4j.repository.query.Query; | ||||
| import org.springframework.data.repository.query.Param; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Repository | ||||
| public interface AuthorRepository extends Neo4jRepository<Author, Long> { | ||||
|     @Query("MATCH (b:Book)-[:WRITTEN_BY]->(a:Author) WHERE a.name = $name AND b.year > $year RETURN b") | ||||
|     List<Book> findBooksAfterYear(@Param("name") String name, @Param("year") Integer year); | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.spring.data.neo4j.repository; | ||||
| 
 | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.domain.Book; | ||||
| import org.springframework.data.neo4j.repository.Neo4jRepository; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Repository | ||||
| public interface BookRepository extends Neo4jRepository<Book, String> { | ||||
|     Book findOneByTitle(String title); | ||||
|     List<Book> findAllByYear(Integer year); | ||||
| } | ||||
| @ -1,23 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.repository; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.domain.Movie; | ||||
| import org.springframework.data.neo4j.annotation.Query; | ||||
| import org.springframework.data.neo4j.repository.Neo4jRepository; | ||||
| import org.springframework.data.repository.query.Param; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @Repository | ||||
| public interface MovieRepository extends Neo4jRepository<Movie, Long> { | ||||
| 
 | ||||
|     Movie findByTitle(@Param("title") String title); | ||||
| 
 | ||||
|     @Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m") | ||||
|     Collection<Movie> findByTitleContaining(@Param("title") String title); | ||||
| 
 | ||||
|     @Query("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) RETURN m.title as movie, collect(a.name) as cast LIMIT {limit}") | ||||
|     List<Map<String, Object>> graph(@Param("limit") int limit); | ||||
| } | ||||
| @ -1,9 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.repository; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.domain.Person; | ||||
| import org.springframework.data.neo4j.repository.Neo4jRepository; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| @Repository | ||||
| public interface PersonRepository extends Neo4jRepository<Person, Long> { | ||||
| } | ||||
| @ -1,51 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j.services; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.repository.MovieRepository; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| @Service | ||||
| @Transactional | ||||
| public class MovieService { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private MovieRepository movieRepository; | ||||
| 
 | ||||
|     private Map<String, Object> toD3Format(Iterator<Map<String, Object>> result) { | ||||
|         List<Map<String, Object>> nodes = new ArrayList<>(); | ||||
|         List<Map<String, Object>> rels = new ArrayList<>(); | ||||
|         int i = 0; | ||||
|         while (result.hasNext()) { | ||||
|             Map<String, Object> row = result.next(); | ||||
|             nodes.add(map("title", row.get("movie"), "label", "movie")); | ||||
|             int target = i; | ||||
|             i++; | ||||
|             for (Object name : (Collection) row.get("cast")) { | ||||
|                 Map<String, Object> actor = map("title", name, "label", "actor"); | ||||
|                 int source = nodes.indexOf(actor); | ||||
|                 if (source == -1) { | ||||
|                     nodes.add(actor); | ||||
|                     source = i++; | ||||
|                 } | ||||
|                 rels.add(map("source", source, "target", target)); | ||||
|             } | ||||
|         } | ||||
|         return map("nodes", nodes, "links", rels); | ||||
|     } | ||||
| 
 | ||||
|     private Map<String, Object> map(String key1, Object value1, String key2, Object value2) { | ||||
|         Map<String, Object> result = new HashMap<>(2); | ||||
|         result.put(key1, value1); | ||||
|         result.put(key2, value2); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     public Map<String, Object> graph(int limit) { | ||||
|         Iterator<Map<String, Object>> result = movieRepository.graph(limit).iterator(); | ||||
|         return toD3Format(result); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,3 @@ | ||||
| spring.neo4j.uri=bolt://localhost:7687 | ||||
| spring.neo4j.authentication.username=neo4j | ||||
| spring.neo4j.authentication.password=password | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 855 B | 
| @ -1,19 +0,0 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.test.context.ActiveProfiles; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.config.MovieDatabaseNeo4jTestConfiguration; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = MovieDatabaseNeo4jTestConfiguration.class) | ||||
| @ActiveProfiles(profiles = "test") | ||||
| public class SpringContextTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenSpringContextIsBootstrapped_thenNoExceptions() { | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,69 @@ | ||||
| package com.baeldung.spring.data.neo4j; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.domain.Book; | ||||
| import com.baeldung.spring.data.neo4j.repository.AuthorRepository; | ||||
| import com.baeldung.spring.data.neo4j.repository.BookRepository; | ||||
| import org.junit.jupiter.api.AfterAll; | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.jupiter.api.BeforeAll; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.neo4j.harness.Neo4j; | ||||
| import org.neo4j.harness.Neo4jBuilders; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; | ||||
| import org.springframework.test.context.DynamicPropertyRegistry; | ||||
| import org.springframework.test.context.DynamicPropertySource; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @DataNeo4jTest | ||||
| public class BookAndAuthorRepositoryIntegrationTest { | ||||
| 
 | ||||
|     private static Neo4j newServer; | ||||
| 
 | ||||
|     @BeforeAll | ||||
|     static void initializeNeo4j() { | ||||
|         newServer = Neo4jBuilders.newInProcessBuilder() | ||||
|           .withDisabledServer() | ||||
|           .withFixture("CREATE (b:Book {isbn: '978-0547928210', name: 'The Fellowship of the Ring', year: 1954})" + | ||||
|             "-[:WRITTEN_BY]->(a:Author {id: 1, name: 'J. R. R. Tolkien'})" + | ||||
|             "CREATE (b2:Book {isbn: '978-0547928203', name: 'The Two Towers', year: 1956})-[:WRITTEN_BY]->(a)") | ||||
|         .build(); | ||||
|     } | ||||
| 
 | ||||
|     @AfterAll | ||||
|     static void stopNeo4j() { | ||||
|         newServer.close(); | ||||
|     } | ||||
| 
 | ||||
|     @DynamicPropertySource | ||||
|     static void neo4jProperties(DynamicPropertyRegistry registry) { | ||||
|         registry.add("spring.neo4j.uri", newServer::boltURI); | ||||
|         registry.add("spring.neo4j.authentication.username", () -> "neo4j"); | ||||
|         registry.add("spring.neo4j.authentication.password", () -> "null"); | ||||
|     } | ||||
| 
 | ||||
|     @Autowired | ||||
|     private BookRepository bookRepository; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private AuthorRepository authorRepository; | ||||
| 
 | ||||
|     @Test | ||||
|     void givenBookExists_whenFindOneByTitle_thenBookIsReturned() { | ||||
|         Book book = bookRepository.findOneByTitle("The Two Towers"); | ||||
|         Assertions.assertEquals("978-0547928203", book.getIsbn()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenOneBookExistsForYear_whenFindAllByYear_thenOneBookIsReturned() { | ||||
|         List<Book> books = bookRepository.findAllByYear(1954); | ||||
|         Assertions.assertEquals(1, books.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenOneBookExistsAfterYear_whenFindBooksAfterYear_thenOneBookIsReturned() { | ||||
|         List<Book> books = authorRepository.findBooksAfterYear("J. R. R. Tolkien", 1955); | ||||
|         Assertions.assertEquals(1, books.size()); | ||||
|     } | ||||
| } | ||||
| @ -1,131 +0,0 @@ | ||||
| package com.baeldung.spring.data.neo4j; | ||||
| 
 | ||||
| import com.baeldung.spring.data.neo4j.config.MovieDatabaseNeo4jTestConfiguration; | ||||
| import com.baeldung.spring.data.neo4j.domain.Movie; | ||||
| import com.baeldung.spring.data.neo4j.domain.Person; | ||||
| import com.baeldung.spring.data.neo4j.domain.Role; | ||||
| import com.baeldung.spring.data.neo4j.repository.MovieRepository; | ||||
| import com.baeldung.spring.data.neo4j.repository.PersonRepository; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.annotation.DirtiesContext; | ||||
| import org.springframework.test.context.ActiveProfiles; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| import static junit.framework.TestCase.assertNull; | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = MovieDatabaseNeo4jTestConfiguration.class) | ||||
| @ActiveProfiles(profiles = "test") | ||||
| public class MovieRepositoryIntegrationTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private MovieRepository movieRepository; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private PersonRepository personRepository; | ||||
| 
 | ||||
|     public MovieRepositoryIntegrationTest() { | ||||
|     } | ||||
| 
 | ||||
|     @Before | ||||
|     public void initializeDatabase() { | ||||
|         System.out.println("seeding embedded database"); | ||||
|         Movie italianJob = new Movie(); | ||||
|         italianJob.setTitle("The Italian Job"); | ||||
|         italianJob.setReleased(1999); | ||||
|         movieRepository.save(italianJob); | ||||
| 
 | ||||
|         Person mark = new Person(); | ||||
|         mark.setName("Mark Wahlberg"); | ||||
|         personRepository.save(mark); | ||||
| 
 | ||||
|         Role charlie = new Role(); | ||||
|         charlie.setMovie(italianJob); | ||||
|         charlie.setPerson(mark); | ||||
|         Collection<String> roleNames = new HashSet<>(); | ||||
|         roleNames.add("Charlie Croker"); | ||||
|         charlie.setRoles(roleNames); | ||||
|         List<Role> roles = new ArrayList<>(); | ||||
|         roles.add(charlie); | ||||
|         italianJob.setRoles(roles); | ||||
|         movieRepository.save(italianJob); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testFindByTitle() { | ||||
|         System.out.println("findByTitle"); | ||||
|         String title = "The Italian Job"; | ||||
|         Movie result = movieRepository.findByTitle(title); | ||||
|         assertNotNull(result); | ||||
|         assertEquals(1999, result.getReleased()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testCount() { | ||||
|         System.out.println("count"); | ||||
|         long movieCount = movieRepository.count(); | ||||
|         assertNotNull(movieCount); | ||||
|         assertEquals(1, movieCount); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testFindAll() { | ||||
|         System.out.println("findAll"); | ||||
|         Collection<Movie> result = (Collection<Movie>) movieRepository.findAll(); | ||||
|         assertNotNull(result); | ||||
|         assertEquals(1, result.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testFindByTitleContaining() { | ||||
|         System.out.println("findByTitleContaining"); | ||||
|         String title = "Italian"; | ||||
|         Collection<Movie> result = movieRepository.findByTitleContaining(title); | ||||
|         assertNotNull(result); | ||||
|         assertEquals(1, result.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testGraph() { | ||||
|         System.out.println("graph"); | ||||
|         List<Map<String, Object>> graph = movieRepository.graph(5); | ||||
|         assertEquals(1, graph.size()); | ||||
|         Map<String, Object> map = graph.get(0); | ||||
|         assertEquals(2, map.size()); | ||||
|         String[] cast = (String[]) map.get("cast"); | ||||
|         String movie = (String) map.get("movie"); | ||||
|         assertEquals("The Italian Job", movie); | ||||
|         assertEquals("Mark Wahlberg", cast[0]); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testDeleteMovie() { | ||||
|         System.out.println("deleteMovie"); | ||||
|         movieRepository.delete(movieRepository.findByTitle("The Italian Job")); | ||||
|         assertNull(movieRepository.findByTitle("The Italian Job")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @DirtiesContext | ||||
|     public void testDeleteAll() { | ||||
|         System.out.println("deleteAll"); | ||||
|         movieRepository.deleteAll(); | ||||
|         Collection<Movie> result = (Collection<Movie>) movieRepository.findAll(); | ||||
|         assertEquals(0, result.size()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							| @ -368,7 +368,6 @@ | ||||
|                 <module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because it doesn't support jakarta API --> | ||||
|                 <module>persistence-modules/java-cassandra</module> <!-- JAVA-21464 cassandra-unit library doesn't support to run with jdk9 and above --> | ||||
|                 <module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844--> | ||||
|                 <module>persistence-modules/spring-data-neo4j</module> | ||||
|                 <module>java-nashorn</module> | ||||
|                 <module>jeromq</module> | ||||
|             </modules> | ||||
| @ -545,7 +544,6 @@ | ||||
|                 <module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because it doesn't support jakarta API --> | ||||
|                 <module>persistence-modules/java-cassandra</module> <!-- JAVA-21464 cassandra-unit library doesn't support to run with jdk9 and above --> | ||||
|                 <module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844--> | ||||
|                 <module>persistence-modules/spring-data-neo4j</module> | ||||
|                 <module>java-nashorn</module> | ||||
|             </modules> | ||||
| 
 | ||||
| @ -940,6 +938,7 @@ | ||||
|                 <module>image-processing</module> | ||||
|                 <module>language-interop</module> | ||||
|                 <module>gradle-modules/gradle/maven-to-gradle</module> | ||||
|                 <module>persistence-modules/spring-data-neo4j</module> | ||||
|             </modules> | ||||
| 
 | ||||
|             <properties> | ||||
| @ -1211,6 +1210,7 @@ | ||||
|                 <module>image-processing</module> | ||||
|                 <module>language-interop</module> | ||||
|                 <module>gradle-modules/gradle/maven-to-gradle</module> | ||||
|                 <module>persistence-modules/spring-data-neo4j</module> | ||||
|             </modules> | ||||
| 
 | ||||
|             <properties> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user