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:
Abhinav Pandey 2023-08-13 09:52:02 +05:30 committed by GitHub
parent 65ee0b068e
commit 0323955992
24 changed files with 257 additions and 766 deletions

View File

@ -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");
}
}

View File

@ -15,53 +15,39 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.neo4j</groupId> <groupId>org.neo4j.test</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId> <artifactId>neo4j-harness</artifactId>
<version>${neo4j-ogm.version}</version> <version>${neo4j-harness.version}</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-data-neo4j</artifactId> <artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>${spring-data-neo4j.version}</version> <version>${spring-boot.version}</version>
</dependency> <exclusions>
<dependency> <exclusion>
<groupId>com.voodoodyne.jackson.jsog</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>jackson-jsog</artifactId> <artifactId>spring-boot-starter-logging</artifactId>
<version>${jackson-jsog.version}</version> </exclusion>
<scope>compile</scope> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> <exclusions>
<dependency> <exclusion>
<groupId>org.neo4j</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>neo4j-ogm-test</artifactId> <artifactId>spring-boot-starter-logging</artifactId>
<version>${neo4j-ogm.version}</version> </exclusion>
<scope>test</scope> </exclusions>
</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>
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<neo4j.version>3.4.6</neo4j.version> <spring-boot.version>2.7.14</spring-boot.version>
<spring-data-neo4j.version>5.0.1.RELEASE</spring-data-neo4j.version> <neo4j-harness.version>5.10.0</neo4j-harness.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>
</properties> </properties>
</project> </project>

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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());
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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> {
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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() {
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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/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/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-cassandra-reactive</module> <!--JAVA-21844-->
<module>persistence-modules/spring-data-neo4j</module>
<module>java-nashorn</module> <module>java-nashorn</module>
<module>jeromq</module> <module>jeromq</module>
</modules> </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/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/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-cassandra-reactive</module> <!--JAVA-21844-->
<module>persistence-modules/spring-data-neo4j</module>
<module>java-nashorn</module> <module>java-nashorn</module>
</modules> </modules>
@ -940,6 +938,7 @@
<module>image-processing</module> <module>image-processing</module>
<module>language-interop</module> <module>language-interop</module>
<module>gradle-modules/gradle/maven-to-gradle</module> <module>gradle-modules/gradle/maven-to-gradle</module>
<module>persistence-modules/spring-data-neo4j</module>
</modules> </modules>
<properties> <properties>
@ -1211,6 +1210,7 @@
<module>image-processing</module> <module>image-processing</module>
<module>language-interop</module> <module>language-interop</module>
<module>gradle-modules/gradle/maven-to-gradle</module> <module>gradle-modules/gradle/maven-to-gradle</module>
<module>persistence-modules/spring-data-neo4j</module>
</modules> </modules>
<properties> <properties>