Skip to content

Instantly share code, notes, and snippets.

@michael-simons
Last active December 21, 2023 06:37
Show Gist options
  • Select an option

  • Save michael-simons/d3137f64ac0b13713fae8e7e1a69367e to your computer and use it in GitHub Desktop.

Select an option

Save michael-simons/d3137f64ac0b13713fae8e7e1a69367e to your computer and use it in GitHub Desktop.
package ac.simons.neo4j.examples;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import org.neo4j.configuration.connectors.BoltConnector;
import org.neo4j.configuration.helpers.SocketAddress;
import org.neo4j.dbms.api.DatabaseManagementServiceBuilder;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.TransactionContext;
public class GraphApplication {
public static void main(String... a) throws IOException {
// This is the db itself, should be long-lived
var graphDb = new DatabaseManagementServiceBuilder(Files.createTempDirectory("neo4j"))
.setConfig(BoltConnector.enabled, true)
.setConfig(BoltConnector.listen_address, new SocketAddress("localhost", 7687))
.build();
// You could also use the graph database api and skip using bolt.
// The advantage of using build also in an embedded scenario: You can switch to a server with ease.
// Same goes for the driver with the connection pool
// The session itself is short-lived
try (
var driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.none());
var session = driver.session()
) {
session.executeWrite(t -> t.run("CREATE (p:Person {name: 'Arnold Schwarzenegger'}) - [:ACTED_IN] -> (:Movie {title: 'The Terminator'})").consume().counters().nodesCreated());
var movies = session.executeRead(GraphApplication::findMovieAndTheirActors);
movies.forEach(System.out::println);
}
graphDb.shutdown();
}
record Person(String name) {
}
record Movie(String title, List<Person>actedIn) {
}
static List<Movie> findMovieAndTheirActors(TransactionContext tx) {
var query = """
MATCH (m:Movie) <- [:ACTED_IN] - (p:Person)
WHERE m.title =~ $movieTitle
RETURN m.title AS title, collect(p.name) AS actors
""";
return tx.run(query, Map.of("movieTitle", ".*The.*")).list(r -> {
var actors = r.get("actors").asList(v -> new Person(v.asString()));
return new Movie(r.get("title").asString(), actors);
});
}
}
<?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>
<groupId>ac.simons.neo4j</groupId>
<artifactId>neo4jtwitch</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<neo4j.version>5.15.0</neo4j.version>
<neo4j-java-driver.version>5.15.0</neo4j-java-driver.version>
</properties>
<dependencies>
<!-- Embbeded instance -->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>${neo4j.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-bolt</artifactId>
<version>${neo4j.version}</version>
</dependency>
<!-- Driver (for connection) -->
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${neo4j-java-driver.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.1.0</version>
<configuration>
<assembleDirectory>${project.build.directory}/assembly</assembleDirectory>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
<programs>
<program>
<mainClass>ac.simons.neo4j.examples.GraphApplication</mainClass>
<id>app</id>
</program>
</programs>
</configuration>
<executions>
<execution>
<id>make-distribution</id>
<goals>
<goal>assemble</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@michael-simons
Copy link
Author

Neo4j Browser is not part of the embedded distribution.
Neo4j embedded inside Spring Boot is not likely to work with recent versions of Neo4j.
To use Neo4j from Spring Boot, use the bolt connector and an externally running Neo4j.

@Podbrushkin
Copy link

Podbrushkin commented Nov 10, 2023

Database of this app cannot be accessed with Neo4j Browser hosted at https://browser.neo4j.io/ either?
I know if db file structure will be created not in TempDirectory as it is but in /target/ directory, it will stay populated after app shutdown and you can run neo4j docker instance which will use this directory, making it possible to observe this data with neo4j browser.

Neo4j embedded inside Spring Boot is not likely to work with recent versions of Neo4j.

It works for me with latest neo4j and Spring Boot as long as HttpConnector is disabled. At least now I know it shouldn't have worked at all, thank you. I wonder how I should've known that Neo4j Embedded isn't compatible with Spring Boot. These compatibility issues between Spring Boot and Neo4j Embedded will be addressed or Neo4j team isn't interested on this matter?

@cybersam
Copy link

cybersam commented Nov 10, 2023

A couple of suggestions:

  1. I think there is a typo. "The advantage of using build" should probably be "The advantage of using bolt".
  2. You should probably schedule deletion of the temp directory via graphDb.deleteOnExit().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment