Merge pull request #14241 from timis1/JAVA-22364

JAVA-22364 Split spring-data-neo4j module
This commit is contained in:
Loredana Crusoveanu 2023-06-16 20:28:03 +03:00 committed by GitHub
commit d55d260870
17 changed files with 710 additions and 174 deletions

5
.gitignore vendored
View File

@ -120,4 +120,7 @@ libraries-2/src/test/resources/crawler4j/**
devDb*.db devDb*.db
#jaxb #jaxb
*.xjb *.xjb
#neo4j
persistence-modules/neo4j/data/**

View File

@ -0,0 +1,15 @@
## Spring Data Neo4j
### Relevant Articles:
- [A Guide to Neo4J with Java](https://www.baeldung.com/java-neo4j)
### Build the Project with Tests Running
```
mvn clean install
```
### Run Tests Directly
```
mvn test
```

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>neo4j</artifactId>
<version>1.0</version>
<name>neo4j</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>persistence-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>${neo4j.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>${neo4j-ogm-core.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>${neo4j-ogm-embedded.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>${neo4j-ogm-bolt-driver.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${neo4j-java-driver.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-jdbc-driver</artifactId>
<version>${neo4j-jdbc.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.voodoodyne.jackson.jsog</groupId>
<artifactId>jackson-jsog</artifactId>
<version>${jackson-jsog.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${neo4j.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>${neo4j.version}</version>
<type>test-jar</type>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</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.testcontainers</groupId>
<artifactId>neo4j</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</exclusion>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<neo4j-java-driver.version>5.6.0</neo4j-java-driver.version>
<neo4j.version>5.8.0</neo4j.version>
<jackson-jsog.version>1.1.2</jackson-jsog.version>
<neo4j-ogm.version>3.1.22</neo4j-ogm.version>
<neo4j-ogm-core.version>4.0.5</neo4j-ogm-core.version>
<neo4j-ogm-embedded.version>3.2.39</neo4j-ogm-embedded.version>
<neo4j-jdbc.version>4.0.9</neo4j-jdbc.version>
<neo4j-ogm-bolt-driver.version>4.0.5</neo4j-ogm-bolt-driver.version>
</properties>
</project>

View File

@ -0,0 +1,50 @@
package com.baeldung.neo4j.domain;
import static org.neo4j.ogm.annotation.Relationship.Direction.INCOMING;
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

@ -0,0 +1,42 @@
package com.baeldung.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

@ -0,0 +1,66 @@
package com.baeldung.neo4j.domain;
import static org.neo4j.ogm.annotation.Relationship.Direction.INCOMING;
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 = 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

@ -0,0 +1,52 @@
package com.baeldung.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

@ -0,0 +1,50 @@
package com.baeldung.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,79 @@
package com.baeldung.neo4j;
import static com.baeldung.neo4j.TestContainersTestBase.DEFAULT_PASSWORD;
import static com.baeldung.neo4j.TestContainersTestBase.getNewBoltConnection;
import static com.baeldung.neo4j.TestContainersTestBase.neo4jServer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
/**
* 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
*/
class Neo4JServerLiveTest {
private static Session session;
private static Driver driver;
@BeforeAll
public static void setup() {
driver = getNewBoltConnection();
}
@AfterAll
public static void tearDown() {
driver.close();
}
@Test
void standAloneDriver() {
session = driver.session();
session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla");
Result result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" +
"WHERE car.make='tesla' and car.model='modelX'" +
"RETURN company.name");
assertTrue(result.hasNext());
assertEquals("Baeldung", result.next().get("company.name").asString());
session.close();
}
@Test
void standAloneJdbc() throws Exception {
String uri = "jdbc:neo4j:" + neo4jServer.getBoltUrl() + "/?user=neo4j,password=" + DEFAULT_PASSWORD + ",scheme=basic";
Connection con = DriverManager.getConnection(uri);
// Querying
try (Statement stmt = con.createStatement()) {
stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla");
ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" +
"WHERE car.make='tesla' and car.model='modelX'" +
"RETURN company.name");
while (rs.next()) {
assertEquals("Baeldung", rs.getString("company.name"));
}
}
con.close();
}
}

View File

@ -1,7 +1,10 @@
package com.baeldung.neo4j; package com.baeldung.neo4j;
import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME;
import java.io.File; import java.io.File;
import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -10,101 +13,111 @@ import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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.GraphDatabaseService;
import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException; import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.factory.GraphDatabaseFactory; 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 { public class Neo4jLiveTest {
private static GraphDatabaseService graphDb; private static GraphDatabaseService graphDb;
private static Transaction transaction;
private static DatabaseManagementService managementService;
@Before @Before
public void setUp() { public void setUp() {
GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory(); managementService = new DatabaseManagementServiceBuilder(new File("data/cars").toPath())
graphDb = graphDbFactory.newEmbeddedDatabase(new File("data/cars")); .setConfig( GraphDatabaseSettings.transaction_timeout, Duration.ofSeconds( 60 ) )
.setConfig( GraphDatabaseSettings.preallocate_logical_logs, false ).build();
graphDb = managementService.database( DEFAULT_DATABASE_NAME );
} }
@After @After
public void tearDown() { public void tearDown() {
graphDb.shutdown(); managementService.shutdown();
} }
@Test @Test
public void testPersonCar() { public void testPersonCar() {
graphDb.beginTx(); transaction = graphDb.beginTx();
Node car = graphDb.createNode(Label.label("Car")); Node car = transaction.createNode(Label.label("Car"));
car.setProperty("make", "tesla"); car.setProperty("make", "tesla");
car.setProperty("model", "model3"); car.setProperty("model", "model3");
Node owner = graphDb.createNode(Label.label("Person")); Node owner = transaction.createNode(Label.label("Person"));
owner.setProperty("firstName", "baeldung"); owner.setProperty("firstName", "baeldung");
owner.setProperty("lastName", "baeldung"); owner.setProperty("lastName", "baeldung");
owner.createRelationshipTo(car, RelationshipType.withName("owner")); owner.createRelationshipTo(car, RelationshipType.withName("owner"));
Result result = graphDb.execute("MATCH (c:Car) <-[owner]- (p:Person) " + Result result = transaction.execute("MATCH (c:Car) <-[owner]- (p:Person) " +
"WHERE c.make = 'tesla'" + "WHERE c.make = 'tesla'" +
"RETURN p.firstName, p.lastName"); "RETURN p.firstName, p.lastName");
Map<String, Object> firstResult = result.next(); Map<String, Object> firstResult = result.next();
Assert.assertEquals("baeldung", firstResult.get("p.firstName")); Assert.assertEquals("baeldung", firstResult.get("p.firstName"));
} }
@Test @Test
public void testCreateNode() { public void testCreateNode() {
transaction = graphDb.beginTx();
graphDb.beginTx(); Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" +
Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" +
"RETURN baeldung"); "RETURN baeldung");
Map<String, Object> firstResult = result.next(); Map<String, Object> firstResult = result.next();
Node firstNode = (Node) firstResult.get("baeldung"); Node firstNode = (Node) firstResult.get("baeldung");
Assert.assertEquals(firstNode.getProperty("name"), "Baeldung"); Assert.assertEquals(firstNode.getProperty("name"), "Baeldung");
} }
@Test @Test
public void testCreateNodeAndLink() { public void testCreateNodeAndLink() {
graphDb.beginTx(); transaction = graphDb.beginTx();
Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla"); "RETURN baeldung, tesla");
Map<String, Object> firstResult = result.next(); Map<String, Object> firstResult = result.next();
Assert.assertTrue(firstResult.containsKey("baeldung")); Assert.assertTrue(firstResult.containsKey("baeldung"));
Assert.assertTrue(firstResult.containsKey("tesla")); Assert.assertTrue(firstResult.containsKey("tesla"));
} }
@Test @Test
public void testFindAndReturn() { public void testFindAndReturn() {
graphDb.beginTx(); transaction = graphDb.beginTx();
transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla"); "RETURN baeldung, tesla");
Result result = graphDb.execute("MATCH (company:Company)-[:owns]-> (car:Car)" + Result result = transaction.execute("MATCH (company:Company)-[:owns]-> (car:Car)" +
"WHERE car.make='tesla' and car.model='modelX'" + "WHERE car.make='tesla' and car.model='modelX'" +
"RETURN company.name"); "RETURN company.name");
Map<String, Object> firstResult = result.next(); Map<String, Object> firstResult = result.next();
Assert.assertEquals(firstResult.get("company.name"), "Baeldung"); Assert.assertEquals(firstResult.get("company.name"), "Baeldung");
} }
@Test @Test
public void testUpdate() { public void testUpdate() {
graphDb.beginTx(); transaction = graphDb.beginTx();
transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla"); "RETURN baeldung, tesla");
Result result = graphDb.execute("MATCH (car:Car)" + Result result = transaction.execute("MATCH (car:Car)" +
"WHERE car.make='tesla'" + "WHERE car.make='tesla'" +
" SET car.milage=120" + " SET car.milage=120" +
" SET car :Car:Electro" + " SET car :Car:Electro" +
@ -127,17 +140,16 @@ public class Neo4jLiveTest {
@Test @Test
public void testDelete() { public void testDelete() {
graphDb.beginTx(); transaction = graphDb.beginTx();
transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla"); "RETURN baeldung, tesla");
graphDb.execute("MATCH (company:Company)" + transaction.execute("MATCH (company:Company)" +
" WHERE company.name='Baeldung'" + " WHERE company.name='Baeldung'" +
" DELETE company"); " DELETE company");
Result result = graphDb.execute("MATCH (company:Company)" + Result result = transaction.execute("MATCH (company:Company)" +
" WHERE company.name='Baeldung'" + " WHERE company.name='Baeldung'" +
" RETURN company"); " RETURN company");
@ -146,14 +158,13 @@ public class Neo4jLiveTest {
@Test @Test
public void testBindings() { public void testBindings() {
graphDb.beginTx(); transaction = graphDb.beginTx();
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("name", "baeldung"); params.put("name", "baeldung");
params.put("make", "tesla"); params.put("make", "tesla");
params.put("model", "modelS"); params.put("model", "modelS");
Result result = graphDb.execute("CREATE (baeldung:Company {name:$name}) " + Result result = transaction.execute("CREATE (baeldung:Company {name:$name}) " +
"-[:owns]-> (tesla:Car {make: $make, model: $model})" + "-[:owns]-> (tesla:Car {make: $make, model: $model})" +
"RETURN baeldung, tesla", params); "RETURN baeldung, tesla", params);

View File

@ -0,0 +1,58 @@
package com.baeldung.neo4j;
import static com.baeldung.neo4j.TestContainersTestBase.getDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.neo4j.ogm.model.Result;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import com.baeldung.neo4j.domain.Car;
import com.baeldung.neo4j.domain.Company;
/**
* 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 Neo4jOgmLiveTest {
private static SessionFactory sessionFactory;
private static Session session;
@BeforeAll
public static void oneTimeSetUp() {
sessionFactory = new SessionFactory(getDriver(), "com.baeldung.neo4j.domain");
session = sessionFactory.openSession();
session.purgeDatabase();
}
@Test
void testOgm() {
Car tesla = new Car("tesla", "modelS");
Company baeldung = new Company("baeldung");
baeldung.setCar(tesla);
session.save(baeldung);
assertEquals(1, session.countEntitiesOfType(Company.class));
Map<String, String> params = new HashMap<>();
params.put("make", "tesla");
Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" +
" WHERE car.make=$make" +
" RETURN company", params);
Map<String, Object> firstResult = result.iterator().next();
assertEquals(1, firstResult.size());
Company actual = (Company) firstResult.get("company");
assertEquals(actual.getName(), baeldung.getName());
}
}

View File

@ -0,0 +1,132 @@
package com.baeldung.neo4j;
import static org.neo4j.ogm.drivers.bolt.driver.BoltDriver.CONFIG_PARAMETER_BOLT_LOGGING;
import java.util.Locale;
import java.util.Optional;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Logging;
import org.neo4j.driver.Session;
import org.neo4j.driver.SessionConfig;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.driver.Driver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.utility.TestcontainersConfiguration;
/**
* Reference: https://github.com/neo4j/neo4j-ogm/blob/master/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/testutil/TestContainersTestBase.java
*/
public class TestContainersTestBase {
public static final Logger LOGGER = LoggerFactory.getLogger(TestContainersTestBase.class);
public static final Driver driver;
public static final String version;
public static final String DEFAULT_IMAGE = "neo4j:5";
public static final String SYS_PROPERTY_ACCEPT_AND_USE_COMMERCIAL_EDITION = "NEO4J_OGM_NEO4J_ACCEPT_AND_USE_COMMERCIAL_EDITION";
public static final String SYS_PROPERTY_IMAGE_NAME = "NEO4J_OGM_NEO4J_IMAGE_NAME";
public static final String SYS_PROPERTY_NEO4J_URL = "NEO4J_OGM_NEO4J_URL";
public static final String SYS_PROPERTY_NEO4J_PASSWORD = "NEO4J_OGM_NEO4J_PASSWORD";
public static final String DEFAULT_PASSWORD = "12345";
public static Neo4jContainer neo4jServer;
public static Configuration.Builder baseConfigurationBuilder;
public static final String NEO4J_URL = Optional.ofNullable(System.getenv(SYS_PROPERTY_NEO4J_URL)).orElse("");
public static final String NEO4J_PASSWORD = Optional.ofNullable(System.getenv(SYS_PROPERTY_NEO4J_PASSWORD)).orElse("").trim();
static {
boolean acceptAndUseCommercialEdition = hasAcceptedAndWantsToUseCommercialEdition();
if (!(NEO4J_URL.isEmpty() || NEO4J_PASSWORD.isEmpty())) {
LOGGER.info("Using Neo4j instance at {}.", NEO4J_URL);
driver = new org.neo4j.ogm.drivers.bolt.driver.BoltDriver();
baseConfigurationBuilder = new Configuration.Builder()
.uri(NEO4J_URL)
.verifyConnection(true)
.withCustomProperty(CONFIG_PARAMETER_BOLT_LOGGING, Logging.slf4j())
.credentials("neo4j", NEO4J_PASSWORD);
driver.configure(baseConfigurationBuilder.build());
version = extractVersionFromBolt();
} else {
LOGGER.info("Using Neo4j test container.");
String imageName = Optional.ofNullable(System.getenv(SYS_PROPERTY_IMAGE_NAME))
.orElse(DEFAULT_IMAGE + (acceptAndUseCommercialEdition ? "-enterprise" : ""));
version = extractVersionFromDockerImage(imageName);
boolean containerReuseSupported = TestcontainersConfiguration
.getInstance().environmentSupportsReuse();
neo4jServer = new Neo4jContainer<>(imageName)
.withReuse(containerReuseSupported);
if (acceptAndUseCommercialEdition) {
neo4jServer.withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes");
}
neo4jServer.withAdminPassword(DEFAULT_PASSWORD).start();
driver = new org.neo4j.ogm.drivers.bolt.driver.BoltDriver();
baseConfigurationBuilder = new Configuration.Builder()
.uri(neo4jServer.getBoltUrl())
.credentials("neo4j", DEFAULT_PASSWORD)
.verifyConnection(true)
.withCustomProperty(CONFIG_PARAMETER_BOLT_LOGGING, Logging.slf4j());
driver.configure(baseConfigurationBuilder.build());
Runtime.getRuntime().addShutdownHook(new Thread(neo4jServer::stop));
}
}
public static org.neo4j.driver.Driver getNewBoltConnection() {
if (neo4jServer != null) {
return GraphDatabase.driver(neo4jServer.getBoltUrl(), AuthTokens.basic("neo4j", DEFAULT_PASSWORD));
} else {
return GraphDatabase.driver(NEO4J_URL, AuthTokens.basic("neo4j", NEO4J_PASSWORD));
}
}
public static boolean hasAcceptedAndWantsToUseCommercialEdition() {
return Optional.ofNullable(
System.getenv(TestContainersTestBase.SYS_PROPERTY_ACCEPT_AND_USE_COMMERCIAL_EDITION))
.orElse("no").toLowerCase(Locale.ENGLISH).equals("yes");
}
public static Driver getDriver() {
return driver;
}
private static String extractVersionFromDockerImage(String imageName) {
return imageName.replace("neo4j:", "").replace("neo4j/neo4j-experimental:", "").replace("-enterprise", "");
}
private static String extractVersionFromBolt() {
org.neo4j.driver.Driver driver = getDriver().unwrap(org.neo4j.driver.Driver.class);
String version;
SessionConfig sessionConfig = SessionConfig.builder().withDefaultAccessMode(AccessMode.READ).build();
try (Session session = driver.session(sessionConfig)) {
version = (String) session.run("CALL dbms.components() YIELD versions").single().get("versions").asList().get(0);
}
return version.toLowerCase(Locale.ENGLISH);
}
}

View File

@ -93,7 +93,6 @@
<!-- <module>spring-data-mongodb</module> FAILED --> <!-- <module>spring-data-mongodb</module> FAILED -->
<module>spring-data-mongodb-2</module> <module>spring-data-mongodb-2</module>
<module>spring-data-mongodb-reactive</module> <module>spring-data-mongodb-reactive</module>
<!-- <module>spring-data-neo4j</module> FAILED -->
<module>spring-data-redis</module> <module>spring-data-redis</module>
<!-- Moved to JDK9+ profiles--> <!-- Moved to JDK9+ profiles-->
<!-- <module>spring-data-rest</module>--> <!-- <module>spring-data-rest</module>-->
@ -113,6 +112,7 @@
<module>spring-data-rest</module> <module>spring-data-rest</module>
<module>java-mongodb</module> <module>java-mongodb</module>
<module>questdb</module> <module>questdb</module>
<module>neo4j</module>
</modules> </modules>
<properties> <properties>

View File

@ -14,26 +14,11 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>${neo4j.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>${neo4j-ogm.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.neo4j</groupId> <groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId> <artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>${neo4j-ogm.version}</version> <version>${neo4j-ogm.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${neo4j-java-driver.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId> <artifactId>spring-data-neo4j</artifactId>
@ -51,24 +36,6 @@
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${neo4j.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>${neo4j.version}</version>
<type>test-jar</type>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.neo4j</groupId> <groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-test</artifactId> <artifactId>neo4j-ogm-test</artifactId>
@ -89,7 +56,6 @@
</dependencies> </dependencies>
<properties> <properties>
<neo4j-java-driver.version>1.6.2</neo4j-java-driver.version>
<neo4j.version>3.4.6</neo4j.version> <neo4j.version>3.4.6</neo4j.version>
<spring-data-neo4j.version>5.0.1.RELEASE</spring-data-neo4j.version> <spring-data-neo4j.version>5.0.1.RELEASE</spring-data-neo4j.version>
<jackson-jsog.version>1.1</jackson-jsog.version> <jackson-jsog.version>1.1</jackson-jsog.version>

View File

@ -1,60 +0,0 @@
package com.baeldung.neo4j;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
@Ignore
public class Neo4JServerLiveTest {
@Test
public void standAloneDriver() {
Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "12345"));
Session session = driver.session();
session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla");
StatementResult result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" +
"WHERE car.make='tesla' and car.model='modelX'" +
"RETURN company.name");
Assert.assertTrue(result.hasNext());
Assert.assertEquals(result.next().get("company.name").asString(), "Baeldung");
session.close();
driver.close();
}
@Test
public void standAloneJdbc() throws Exception {
Connection con = DriverManager.getConnection("jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic");
// Querying
try (Statement stmt = con.createStatement()) {
stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
"-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
"RETURN baeldung, tesla");
ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" +
"WHERE car.make='tesla' and car.model='modelX'" +
"RETURN company.name");
while (rs.next()) {
Assert.assertEquals(rs.getString("company.name"), "Baeldung");
}
}
con.close();
}
}

View File

@ -1,47 +0,0 @@
package com.baeldung.neo4j;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.model.Result;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import com.baeldung.spring.data.neo4j.domain.Car;
import com.baeldung.spring.data.neo4j.domain.Company;
public class Neo4jOgmLiveTest {
@Test
public void testOgm() {
Configuration conf = new Configuration.Builder().build();
SessionFactory factory = new SessionFactory(conf, "com.baeldung.spring.data.neo4j.domain");
Session session = factory.openSession();
Car tesla = new Car("tesla", "modelS");
Company baeldung = new Company("baeldung");
baeldung.setCar(tesla);
session.save(baeldung);
Assert.assertEquals(1, session.countEntitiesOfType(Company.class));
Map<String, String> params = new HashMap<>();
params.put("make", "tesla");
Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" +
" WHERE car.make=$make" +
" RETURN company", params);
Map<String, Object> firstResult = result.iterator().next();
Assert.assertEquals(firstResult.size(), 1);
Company actual = (Company) firstResult.get("company");
Assert.assertEquals(actual.getName(), baeldung.getName());
}
}

View File

@ -369,6 +369,7 @@
<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>
</modules> </modules>
</profile> </profile>
@ -545,6 +546,7 @@
<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>
</modules> </modules>
</profile> </profile>