Update Neo4j extension to use Spring Data Neo4j. (#125)

Move away from the Neo4j OGM usage because Spring Data Neo4j
fits better in the ecosystem, spring-batch is settled in.

Previously there was no visible difference to users because Spring Data Neo4j
was based on Neo4j OGM which isn't the case anymore.
This commit is contained in:
Gerrit Meier
2024-08-20 17:50:41 +02:00
committed by GitHub
parent 42093bc813
commit 41cbb93142
11 changed files with 1242 additions and 1058 deletions

View File

@@ -7,16 +7,11 @@ This extension contains an `ItemReader` and `ItemWriter` implementations for [Ne
The `Neo4jItemReader` can be configured as follows:
```java
SessionFactory sessionFactory = ...
Neo4jItemReader<String> itemReader = new Neo4jItemReaderBuilder<String>()
.sessionFactory(sessionFactory)
.name("itemReader")
.targetType(String.class)
.startStatement("n=node(*)")
.orderByStatement("n.age")
.matchStatement("n -- m")
.whereStatement("has(n.name)")
.returnStatement("m")
Neo4jItemReader<User> reader = new Neo4jItemReaderBuilder<User>()
.neo4jTemplate(neo4jTemplate)
.name("userReader")
.statement(Cypher.match(userNode).returning(userNode))
.targetType(User.class)
.pageSize(50)
.build();
```
@@ -24,8 +19,93 @@ Neo4jItemReader<String> itemReader = new Neo4jItemReaderBuilder<String>()
The `Neo4jItemWriter` can be configured as follows:
```java
SessionFactory sessionFactory = ...
Neo4jItemWriter<String> writer = new Neo4jItemWriterBuilder<String>()
.sessionFactory(sessionFactory)
Neo4jItemWriter<User> writer = new Neo4jItemWriterBuilder<User>()
.neo4jTemplate(neo4jTemplate)
.neo4jDriver(driver)
.neo4jMappingContext(mappingContext)
.build();
```
## Minimal Spring Boot example
Additional to the already existing dependencies in a new Spring Boot application,
`spring-boot-starter-data-neo4j`, `spring-batch-neo4j` and the `spring-boot-starter-batch` are needed
but `spring-jdbc` and `spring-boot-starter-jdbc` must be explicitly excluded.
The exclusions are mandatory to avoid any need for JDBC-based connections, like JDBC URI etc.
See the following _build.gradle_ dependency definition for a minimal example.
```groovy
dependencies {
implementation ('org.springframework.boot:spring-boot-starter-batch') {
exclude group: 'org.springframework', module: 'spring-jdbc'
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-jdbc'
}
// current development version 0.2.0-SNAPSHOT
implementation 'org.springframework.batch.extensions:spring-batch-neo4j'
implementation 'org.springframework.boot:spring-boot-starter-data-neo4j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.batch:spring-batch-test'
}
```
An example of the usage can be seen in the following example, implementing the `CommandLineRunner` interface.
```java
@SpringBootApplication
public class TestSpringBatchApplication implements CommandLineRunner {
// those dependencies are created by Spring Boot's
// spring-data-neo4j autoconfiguration
@Autowired
private Driver driver;
@Autowired
private Neo4jMappingContext mappingContext;
@Autowired
private Neo4jTemplate neo4jTemplate;
public static void main(String[] args) {
SpringApplication.run(TestSpringBatchApplication.class, args);
}
@Override
public void run(String... args) {
// writing
Neo4jItemWriter<User> writer = new Neo4jItemWriterBuilder<User>()
.neo4jTemplate(neo4jTemplate)
.neo4jDriver(driver)
.neo4jMappingContext(mappingContext)
.build();
writer.write(Chunk.of(new User("id1", "ab"), new User("id2", "bb")));
// reading
org.neo4j.cypherdsl.core.Node userNode = Cypher.node("User");
Neo4jItemReader<User> reader = new Neo4jItemReaderBuilder<User>()
.neo4jTemplate(neo4jTemplate)
.name("userReader")
.statement(Cypher.match(userNode).returning(userNode))
.targetType(User.class)
.build();
List<User> allUsers = new ArrayList<>();
User user = null;
while ((user = reader.read()) != null) {
System.out.printf("Found user: %s%n", user.name);
allUsers.add(user);
}
// deleting
writer.setDelete(true);
writer.write(Chunk.of(allUsers.toArray(new User[]{})));
}
@Node("User")
public static class User {
@Id public final String id;
public final String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
}
}
```