Created
November 14, 2023 23:29
-
-
Save Podbrushkin/54518ad6c4835706fd3344f01ea6acc9 to your computer and use it in GitHub Desktop.
Spring Data Neo4j MRE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp; | |
import java.io.File; | |
import java.time.Duration; | |
import java.time.LocalDate; | |
import org.neo4j.configuration.GraphDatabaseSettings; | |
import org.neo4j.configuration.connectors.BoltConnector; | |
import org.neo4j.cypherdsl.core.renderer.Configuration; | |
import org.neo4j.cypherdsl.core.renderer.Dialect; | |
import org.neo4j.dbms.api.DatabaseManagementService; | |
import org.neo4j.dbms.api.DatabaseManagementServiceBuilder; | |
import org.neo4j.graphdb.GraphDatabaseService; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.boot.CommandLineRunner; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; | |
import myapp.model.Image; | |
import myapp.model.Person; | |
import myapp.repo.ImageRepositoryNeo4j; | |
import myapp.repo.PersonRepositoryNeo4j; | |
@SpringBootApplication | |
@EnableNeo4jRepositories | |
public class DemoApplication { | |
private Logger log = LoggerFactory.getLogger(getClass()); | |
public static void main(String[] args) { | |
SpringApplication.run(DemoApplication.class, args); | |
} | |
@Bean | |
public Configuration cypherDslConfiguration() { | |
return Configuration.newConfig().withDialect(Dialect.NEO4J_5).build(); | |
} | |
//https://neo4j.com/docs/java-reference/current/java-embedded/setup/ | |
@Bean | |
public DatabaseManagementService databaseManagementService() { | |
DatabaseManagementService managementService = new | |
DatabaseManagementServiceBuilder(new File("target/mydb").toPath()) | |
.setConfig(GraphDatabaseSettings.transaction_timeout, Duration.ofSeconds( 60 ) ) | |
.setConfig( BoltConnector.enabled, true ) | |
.setConfig(BoltConnector.encryption_level, BoltConnector.EncryptionLevel.DISABLED) | |
.build(); | |
registerShutdownHook(managementService); | |
return managementService; | |
} | |
@Bean | |
public GraphDatabaseService graphDatabaseService(DatabaseManagementService managementService) { | |
GraphDatabaseService graphDb = | |
managementService.database(GraphDatabaseSettings.DEFAULT_DATABASE_NAME); | |
log.info("Neo4j database Embedded instance is available: {}", graphDb.isAvailable()); | |
return graphDb; | |
} | |
private static void registerShutdownHook(final DatabaseManagementService managementService) { | |
Runtime.getRuntime().addShutdownHook(new Thread() { | |
@Override | |
public void run() { | |
managementService.shutdown(); | |
} | |
}); | |
} | |
@Bean | |
CommandLineRunner demo(PersonRepositoryNeo4j personRepository, | |
ImageRepositoryNeo4j imageRepository) { | |
return args -> { | |
Person greg = new Person("Greg", LocalDate.of(1991,1,1)); | |
Person roy = new Person("Roy", LocalDate.of(1992,2,2)); | |
Person greg2 = new Person("Greg", LocalDate.of(1993,3,3)); | |
greg = personRepository.save(greg); | |
roy = personRepository.save(roy); | |
greg2 = personRepository.save(greg2); | |
var img1 = new Image("/blabla1.jpg"); | |
var img2 = new Image("/blabla2.jpg"); | |
img1.getPeople().add(greg); | |
img1.getPeople().add(roy); | |
img2.getPeople().add(greg); | |
img2.getPeople().add(greg2); | |
img1 = imageRepository.save(img1); | |
img2 = imageRepository.save(img2); | |
// now greg1991 is depicted in 2 images and greg1993 in 1 image | |
var freshPerson = personRepository.findOneByBirthday(LocalDate.of(1993,3,3)); | |
// this one should return '1' but brings exception: | |
var count = imageRepository.countByPeopleContains(freshPerson); | |
log.info("Greg1993 is depicted in {} images.", count); | |
}; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp.model; | |
import java.util.HashSet; | |
import java.util.Set; | |
import org.springframework.data.neo4j.core.schema.GeneratedValue; | |
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 org.springframework.data.neo4j.core.schema.Relationship.Direction; | |
@Node("Image") | |
public class Image { | |
@Id | |
@GeneratedValue | |
private String id; | |
private String filePath; | |
@Relationship(type = "DEPICTS", direction = Direction.OUTGOING) | |
private Set<Person> people = new HashSet<>(); | |
public Image(String filePath) { | |
this.filePath = filePath; | |
} | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getFilePath() { | |
return filePath; | |
} | |
public void setFilePath(String filePath) { | |
this.filePath = filePath; | |
} | |
public Set<Person> getPeople() { | |
return people; | |
} | |
public void setPeople(Set<Person> people) { | |
this.people = people; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp.repo; | |
import org.springframework.data.neo4j.repository.Neo4jRepository; | |
import org.springframework.data.neo4j.repository.query.Query; | |
import org.springframework.data.repository.query.Param; | |
import myapp.model.Image; | |
import myapp.model.Person; | |
public interface ImageRepositoryNeo4j extends Neo4jRepository<Image, String> { | |
@Query(""" | |
MATCH (i:Image) -[:DEPICTS] -> (p:Person) | |
WHERE id(p) = id($person) | |
RETURN count(i) | |
""") | |
// Invalid input for function 'id()': to be a node or relationship, but it was `Map`; | |
public Integer countByPeopleContains(@Param("person") Person person); | |
@Query(""" | |
MATCH (i:Image) -[:DEPICTS] -> (p:Person {name: $person}) | |
RETURN count(i) | |
""") | |
public Integer countByPeopleContains(@Param("person") String personName); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp.model; | |
import java.time.LocalDate; | |
import org.springframework.data.neo4j.core.schema.GeneratedValue; | |
import org.springframework.data.neo4j.core.schema.Id; | |
import org.springframework.data.neo4j.core.schema.Node; | |
@Node("Person") | |
public class Person { | |
@Id | |
@GeneratedValue | |
private String id; | |
private String name; | |
private LocalDate birthday; | |
public Person(String name, LocalDate birthday) { | |
this.name = name; | |
this.birthday = birthday; | |
} | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public LocalDate getBirthday() { | |
return birthday; | |
} | |
public void setBirthday(LocalDate birthday) { | |
this.birthday = birthday; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp.repo; | |
import java.time.LocalDate; | |
import org.springframework.data.neo4j.repository.Neo4jRepository; | |
import myapp.model.Person; | |
public interface PersonRepositoryNeo4j extends Neo4jRepository<Person, String> { | |
Person findOneByName(String name); | |
Person findOneByBirthday(LocalDate name); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<parent> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-parent</artifactId> | |
<version>3.1.5</version> | |
<relativePath/> <!-- lookup parent from repository --> | |
</parent> | |
<groupId>com.example</groupId> | |
<artifactId>demo</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<name>demo</name> | |
<description>execute `mvn clean spring-boot:run -e` in this directory to get an exception</description> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<java.version>17</java.version> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>com.fasterxml.jackson.core</groupId> | |
<artifactId>jackson-databind</artifactId> | |
<version>2.15.0-rc2</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-web</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-data-neo4j</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>org.neo4j</groupId> | |
<artifactId>neo4j</artifactId> | |
<version>5.13.0</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-maven-plugin</artifactId> | |
</plugin> | |
</plugins> | |
</build> | |
</project> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In empty dir: