DATAGRAPH-1421 - Add another round of copy editing.

Co-authored-by: Michael Simons <michael@simons.ac>
This commit is contained in:
Florent Biville
2020-11-04 09:43:14 +01:00
committed by GitHub
parent 37e2f90b21
commit 8a3ac2d1ae
17 changed files with 86 additions and 93 deletions

View File

@@ -4,13 +4,14 @@ image:https://spring.io/badges/spring-data-neo4j/ga.svg[Spring Data Neo4j,link=h
:sectanchors:
// tag::properties[]
:neo4jGroupId: org.springframework.data.neo4j
:neo4jGroupId: org.springframework.data
:artifactId: spring-data-neo4j
:groupIdStarter: org.springframework.boot
:artifactIdStarter: spring-boot-starter-data-neo4j
:neo4j-version: 4.0.4
:spring-boot-version: 2.4.0.M3
:spring-data-neo4j-version: 6.0.0-SNAPSHOT
:neo4j-version: 4.1.3
:spring-boot-version: 2.4.0-RC1
:spring-data-neo4j-version: 6.0.0
// end::properties[]
[abstract]
@@ -32,7 +33,7 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
== Manual
For a gentle introduction and some getting started guides, please use our
https://neo4j.github.io/sdn-rx[Manual].
https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#reference[Manual].
== Getting Started
@@ -60,7 +61,7 @@ spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
----
Please have a look at our https://neo4j.github.io/sdn-rx[manual] for an overview about the architecture, how to define
Please have a look at our https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#reference[manual] for an overview about the architecture, how to define
mappings and more.
==== Without Spring Boot

View File

@@ -11,8 +11,8 @@ and annotations.
[source,cypher,role="constraint"]
.@API Guardian annotations must not be used on fields
----
MATCH (c:Java) - [:ANNOTATED_BY] -> (a) - [:OF_TYPE] -> (t:Type {fqn: 'org.apiguardian.api.API'}),
(p) - [:DECLARES] -> (c)
MATCH (c:Java)-[:ANNOTATED_BY]->(a)-[:OF_TYPE]->(t:Type {fqn: 'org.apiguardian.api.API'}),
(p)-[:DECLARES]->(c)
WHERE c:Member AND NOT c:Constructor
RETURN p.fqn, c.name
----
@@ -23,8 +23,8 @@ Public interfaces, classes or annotations are either part of internal or public
[source,cypher,role="concept",verify=rowCount,rowCountMin=0]
.Define which Java artifacts are part of internal or public API
----
MATCH (c:Java) - [:ANNOTATED_BY] -> (a) - [:OF_TYPE] -> (t:Type {fqn: 'org.apiguardian.api.API'}),
(a) - [:HAS] -> ({name: 'status'}) - [:IS] -> (s)
MATCH (c:Java)-[:ANNOTATED_BY]->(a)-[:OF_TYPE]->(t:Type {fqn: 'org.apiguardian.api.API'}),
(a)-[:HAS]->({name: 'status'})-[:IS]->(s)
WHERE ANY (label IN labels(c) WHERE label in ['Interface', 'Class', 'Annotation'])
WITH c, trim(split(s.signature, ' ')[1]) AS status
WITH c, status,
@@ -33,7 +33,7 @@ WITH c, status,
ELSE 'Public'
END AS type
MERGE (a:Api {type: type, status: status})
MERGE (c) - [:IS_PART_OF] -> (a)
MERGE (c)-[:IS_PART_OF]->(a)
RETURN c,a
----
@@ -45,7 +45,7 @@ See ADR-003.
[source,cypher,role="constraint",requiresConcepts="api:api-guardian-api-concept"]
.Non abstract, public classes that are only part of internal API must be final
----
MATCH (c:Class) - [:IS_PART_OF] -> (:Api {type: 'Internal'})
MATCH (c:Class)-[:IS_PART_OF]->(:Api {type: 'Internal'})
WHERE c.visibility = 'public'
AND coalesce(c.abstract, false) = false
AND NOT exists(c.final)

View File

@@ -8,9 +8,9 @@ Most of the time, the package structure under `org.springframework.data.neo4j` s
.The mapping package must not depend on any other SDN packages than `schema` and `convert`
----
MATCH (a:Main:Artifact)
OPTIONAL MATCH (a) -[:CONTAINS]-> (s:Package) WHERE s.fqn in ['org.springframework.data.neo4j.core.schema', 'org.springframework.data.neo4j.core.convert']
OPTIONAL MATCH (a)-[:CONTAINS]->(s:Package) WHERE s.fqn in ['org.springframework.data.neo4j.core.schema', 'org.springframework.data.neo4j.core.convert']
WITH collect(s) as allowed, a
MATCH (a) -[:CONTAINS]-> (p1:Package) -[:DEPENDS_ON]-> (p2:Package) <-[:CONTAINS]- (a)
MATCH (a)-[:CONTAINS]->(p1:Package)-[:DEPENDS_ON]->(p2:Package)<-[:CONTAINS]-(a)
WHERE p1.fqn = 'org.springframework.data.neo4j.core.mapping'
AND NOT (p2 in allowed OR (p1) -[:CONTAINS]-> (p2))
RETURN p1,p2
@@ -21,7 +21,7 @@ RETURN p1,p2
.The public support packages must not depend directly on the mapping package
----
MATCH (a:Main:Artifact)
MATCH (a) -[:CONTAINS]-> (p1:Package)
MATCH (a)-[:CONTAINS]->(p1:Package)
WHERE p1.fqn in [
'org.springframework.data.neo4j.core.convert',
'org.springframework.data.neo4j.core.schema',
@@ -29,8 +29,8 @@ WHERE p1.fqn in [
'org.springframework.data.neo4j.core.transaction'
]
WITH p1, a
MATCH (p1) - [:CONTAINS] -> (t:Type)
MATCH (t) - [:DEPENDS_ON] -> (t2:Type) <- [:CONTAINS] - (p2:Package) <-[:CONTAINS]- (a)
MATCH (p1)-[:CONTAINS]->(t:Type)
MATCH (t)-[:DEPENDS_ON]->(t2:Type)<-[:CONTAINS]-(p2:Package)<-[:CONTAINS]-(a)
WHERE t2.fqn <> 'org.springframework.data.neo4j.core.mapping.Neo4jPersistentProperty'
AND p2.fqn = 'org.springframework.data.neo4j.core.mapping'
RETURN t

View File

@@ -14,9 +14,9 @@
Choosing JDK 8 is a decision influenced by various aspects
* SDN is a Spring Data project.
Spring Data commons baseline is still JDK 8 and so is Spring Frameworks baseline.
Thus it is only natural to keep the JDK 8 baseline.
* While there is an increase of projects started with JDK 11 (which is Oracles current LTS release of Java), many existing projects are still on JDK 8. We don't want to lose them as users right from the start.
Spring Data commons baseline is still JDK 8 and so is Spring Framework's baseline.
Thus, it is only natural to keep the JDK 8 baseline.
* While there is an increase of projects started with JDK 11 (which is Oracle's current LTS release of Java), many existing projects are still on JDK 8. We don't want to lose them as users right from the start.
== Running the build
@@ -49,7 +49,7 @@ Java HotSpot(TM) 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)
==== Using the default image
If you don't have https://en.wikipedia.org/wiki/Docker_(software)[Docker] installed, head over to https://www.docker.com/products/docker-desktop[Docker Desktop].
In short, Docker is a tool that helps you running lightweight software images using OS-level virtualization in so called containers.
In short, Docker is a tool that helps you running lightweight software images using OS-level virtualization in so-called containers.
Our build uses https://www.testcontainers.org/modules/databases/neo4j/[Testcontainers Neo4j] to bring up a database instance.
@@ -71,9 +71,6 @@ $ mvnw.cmd clean verify
The output should be similar.
At the moment, this build tests against Neo4j 3.5, as 4.0 is not yet available on Docker Hub.
As a consequence, tests requiring a reactive capable database, are skipped, as this is a feature of Neo4j 4.0.
==== Using another image
The image version to use can be configured through an environmental variable like this:
@@ -97,7 +94,6 @@ Building against a locally running database is faster, as it does not restart a
We do this a lot during our development.
You can get a copy of Neo4j at our https://neo4j.com/download-center/#enterprise[download center] free of charge.
Especially you can get https://neo4j.com/download-center/?ref=blog/#prerelease[the current prelease of Neo4j 4.0], supporting all the reactive features.
Please download the version applicable to your operating system and follow the instructions to start it.
A required step is to open a browser and go to http://localhost:7474 after you started the database and change the default password from `neo4j` to something of your liking.

View File

@@ -205,7 +205,7 @@ If you need multiple converters in your application, you can add as many as you
=== For specific attributes only
If you need conversions only for some specific attributes, we provide `@ConvertWith`.
This is an annotation that can be put on attributes carrying a `Neo4jPersistentPropertyConverter` on it's `converter` attribute
This is an annotation that can be put on attributes carrying a `Neo4jPersistentPropertyConverter` on its `converter` attribute
and an optional `Neo4jPersistentPropertyConverterFactory` to construct the former.
With an implementation of `Neo4jPersistentPropertyConverter` all specific conversions for a given type can be addressed.
@@ -214,7 +214,7 @@ We provide `@DateLong` and `@DateString` as meta-annotated annotations for backw
[[composite-properties]]
==== Composite properties
With `@CompositeProperty`, attributes of type `Map<String, Object>` or Map<? extends Enum, Object>` can be stored as composite properties.
With `@CompositeProperty`, attributes of type `Map<String, Object>` or `Map<? extends Enum, Object>` can be stored as composite properties.
All entries inside the map will be added as properties to the node or relationship containing the property.
Either with a configured prefix or prefixed with the name of the property.
While we only offer that feature for maps out of the box, you can `Neo4jPersistentPropertyToMapConverter` and configure it

View File

@@ -10,7 +10,7 @@ Having skipped more than one major upgrade::
While Neo4j-OGM can be used stand-alone, Spring Data Neo4j cannot.
It depends to large extend on the Spring Data and therefore, on the Spring Framework itself, which eventually affects large parts of your application.
Depending on how the application has been structured, that is, how much the any of the framework part leaked into your business code, the more you have to adapt your application.
It get's worse when you have more than one Spring Data module in your application, if you accessed a relational database in the same service layer as your graph database.
It gets worse when you have more than one Spring Data module in your application, if you accessed a relational database in the same service layer as your graph database.
Updating two object mapping frameworks is not fun.
Relying on a embedded database configured through Spring Data itself::
The embedded database in a SDN+OGM project is configured by Neo4j-OGM.
@@ -23,7 +23,7 @@ Spring Data however depends on Spring Framework and than the arguments from the
Being unsure about which building blocks to include::
It's not easy to get the terms right.
We wrote the building blocks of an SDN+OGM setting https://michael-simons.github.io/neo4j-sdn-ogm-tips/what_are_the_building_blocks_of_sdn_and_ogm.html[here].
It may be so that all of them have been added by coincidence and you're dealing with a lof of conflicting dependencies.
It may be so that all of them have been added by coincidence and you're dealing with a lot of conflicting dependencies.
TIP: Backed by those observations, we recommend to make sure you're using only the Bolt or http transport in your current application before switching from SDN+OGM to SDN.
Thus, your application and the access layer of your application is to large extend independent from the databases version.
@@ -38,11 +38,11 @@ First, you must make sure that your application runs against Neo4j in server mod
=== You're on embedded
You have added `org.neo4j:neo4j-ogm-embedded-driver` and `org.neo4j:neo4j` to you project and starting the database via OGM facilities.
This is no longer supported and you have to setup a standard Neo4j server (both standalone and cluster are supported).
This is no longer supported and you have to set up a standard Neo4j server (both standalone and cluster are supported).
The above dependencies have to be removed.
Migrating from the embedded solution is probably the toughest migration, as you need to setup a server, too.
Migrating from the embedded solution is probably the toughest migration, as you need to set up a server, too.
It is however the one that gives you much value in itself:
In the future, you will be able to upgrade the database itself without having to consider your application framework, and your data access framework as well.
@@ -74,7 +74,7 @@ With our starter in place, all the necessary bits apart from the connection URL
.Old and new properties compared
----
# Old
spring.data.neo4j.embedded.enabled=false # No longer support
spring.data.neo4j.embedded.enabled=false # No longer supported
spring.data.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret
@@ -85,11 +85,11 @@ spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
----
WARNING: Those new properties might change in the future again when SDN and the driver will eventually replace the old setup fully.
WARNING: Those new properties might change in the future again when SDN and the driver eventually fully replace the old setup.
And finally, add the new dependency, see <<getting-started>> for both Gradle and Maven.
You're than ready to replace annotations:
You're then ready to replace annotations:
[cols="2*",options="header"]
|===
@@ -126,7 +126,7 @@ We will add to the list above as we support additional features.
=== Bookmarkmanagement
Both `@EnableBookmarkManagement` and `@UseBookmark` as well as the `org.springframework.data.neo4j.bookmark.BookmarkManager`
interface and it's only implementation `org.springframework.data.neo4j.bookmark.CaffeineBookmarkManager` are gone and are not needed anymore.
interface and its only implementation `org.springframework.data.neo4j.bookmark.CaffeineBookmarkManager` are gone and are not needed anymore.
SDN uses Bookmarks for all transactions, without configuration.
You can remove the bean declaration of `CaffeineBookmarkManager` as well as the the dependency to `com.github.ben-manes.caffeine:caffeine`.

View File

@@ -95,7 +95,7 @@ NOTE: Make sure you use the same driver instance for the client as you used for
in case you have enabled transactions.
The client won't be able to synchronize transactions if you use another instance of a driver.
Our Spring Boot starter provide a ready to use bean of the Neo4j Client that fit the environment (imperative or reactive) and you usually don't have to configure your own instance.
Our Spring Boot starter provide a ready to use bean of the Neo4j Client that fits the environment (imperative or reactive) and you usually don't have to configure your own instance.
== Usage
@@ -176,19 +176,19 @@ ResultSummary resultSummary = imperativeClient
SummaryCounters counters = resultSummary.counters();
System.out.println(counters.nodesDeleted() + " nodes have been deleted")
----
<.> Here the query is triggered immediate.
<.> Here the query is immediately triggered.
=== Mapping parameters
Queries can contain named parameters (`$someName`).
The Neo4j client allows comfortable binding to those.
Queries can contain named parameters (`$someName`) and the Neo4j client makes it easy to bind values to them.
NOTE: The client doesn't check whether all parameters are bound or whether there are to many values.
NOTE: The client doesn't check whether all parameters are bound or whether there are too many values.
That is left to the driver.
However the client prevents you from using a parameter name twice.
However, the client prevents you from using a parameter name twice.
You can either map simple types that the Java driver understands or complex classes.
Please have a look at the https://neo4j.com/docs/driver-manual/current/cypher-values/#driver-neo4j-type-system[drivers manual], to see which simple types are understood.
You can either bind simple types that the Java driver understands without conversion or complex classes.
For complex classes you need to provide a binder function as shown in <<neo4j-client-binder,this listing>>.
Please have a look at the https://neo4j.com/docs/driver-manual/current/cypher-workflow/#driver-type-mapping[drivers manual], to see which simple types are supported.
[[neo4j-client-mapping-simple-types]]
[source,java]
@@ -282,14 +282,14 @@ Mono<ResultSummary> summary = client
})
.run();
----
<.> The with method allows for specifying the binder function.
<.> The `with` method allows for specifying the binder function.
=== Working with result objects
Both clients return collections or publishers of maps (`Map<String, Object>`).
Those maps corresponds exactly with the records that a query might have produced.
Those maps correspond exactly with the records that a query might have produced.
In addition, you can plugin your own `BiFunction<TypeSystem, Record, T>` through `fetchAs` to reproduce your domain object.
In addition, you can plug in your own `BiFunction<TypeSystem, Record, T>` through `fetchAs` to reproduce your domain object.
[[neo4j-client-reader]]
[source,java]

View File

@@ -13,7 +13,7 @@ or of course with a simple script upfront.
=== Statically configured
Configure the database name to use in your Spring Boot configuration like this (The same property applies of course for YML or environment based configuration, with Spring Boots conventions applied):
Configure the database name to use in your Spring Boot configuration like this (the same property applies of course for YML or environment based configuration, with Spring Boot's conventions applied):
[source,properties]
----
@@ -47,7 +47,7 @@ include::../../../../src/test/java/org/springframework/data/neo4j/documentation/
NOTE: Be careful that you don't mix up entities retrieved from one database with another database.
The database name is requested for each new transaction, so you might end up with less or more entities than expected when changing the database name in between calls.
Or worse, you could inevitable store the wrong entities in the wrong database.
Or worse, you could inevitably store the wrong entities in the wrong database.
== Do I need specific configuration so that transactions work seamless with a Neo4j Causal Cluster?
@@ -82,13 +82,13 @@ You are free to use the following, equivalent Spring Data annotations:
== How do I use assigned ids?
Just `@Id` without `@GeneratedValue` and fill your id attribute via a constructor parameter or a setter or _wither_.
Just use `@Id` without `@GeneratedValue` and fill your id attribute via a constructor parameter or a setter or _wither_.
See this https://medium.com/neo4j/neo4j-ogm-and-spring-data-neo4j-a55a866df68c[blog post] for some general remarks about finding good ids.
== How do I use externally generated ids?
We provide the interface `org.springframework.data.neo4j.core.schema.IdGenerator`.
Implement it anyway you want and configure your implementation like this:
Implement it in any way you want and configure your implementation like this:
[source,java]
.ThingWithGeneratedId.java
@@ -124,7 +124,7 @@ NOTE: Setters are not required on non-final fields for the id.
== Do I have to create repositories for each domain class?
No.
Have a look at the <<sdn-building-blocks, SDN building blocks>> and find the `Neo4jTemplate` respectively the `ReactiveNeo4jTemplate.`
Have a look at the <<sdn-building-blocks, SDN building blocks>> and find the `Neo4jTemplate` or the `ReactiveNeo4jTemplate`.
Those templates know your domain and provide all necessary basic CRUD methods for retrieving, writing and counting entities.
@@ -229,7 +229,7 @@ The following dependency is required for the solutions described above:
[source,xml,subs="verbatim,attributes"]
----
<dependency>
<groupId>{springGroupId}</groupId>
<groupId>{neo4jGroupId}</groupId>
<artifactId>{artifactId}</artifactId>
<version>{spring-data-neo4j-version}</version>
</dependency>

View File

@@ -5,7 +5,7 @@ We provide a Spring Boot starter for SDN.
Please include the starter module via your dependency management and configure the bolt URL to use, for example `org.neo4j.driver.uri=bolt://localhost:7687`.
The starter assumes that the server has disabled authentication.
As the SDN starter depends on the starter for the Java Driver, all things regarding configuration said there, apply here as well.
For a reference of the available properties, use your IDEs autocompletion in the `org.neo4j.driver` namespace or look at the link:{java-driver-starter-href}/blob/master/docs/manual.adoc[dedicated manual].
For a reference of the available properties, use your IDEs autocompletion in the `org.neo4j.driver` namespace or look at the link:{java-driver-starter-href}/blob/master/docs/manual/index.adoc[dedicated manual].
SDN supports
@@ -14,7 +14,6 @@ SDN supports
Those are all included in the same binary.
The reactive programming model requires a 4.0 Neo4j server on the database side and reactive Spring on the other hand.
Have a look at the link:{gh-base}/tree/master/examples[examples directory] for all examples.
== Prepare the database
@@ -65,7 +64,7 @@ As this starter is not yet on the initializer, you will have to add the followin
.Inclusion of the spring-data-neo4j-spring-boot-starter in a Maven project
----
<dependency>
<groupId>{groupId}</groupId>
<groupId>{groupIdStarter}</groupId>
<artifactId>{artifactIdStarter}</artifactId>
</dependency>
----
@@ -94,7 +93,7 @@ The dependency for Gradle looks like this and must be added to `build.gradle`:
.Inclusion of the spring-data-neo4j-spring-boot-starter in a Gradle project
----
dependencies {
implementation '{groupId}:{artifactIdStarter}'
implementation '{groupIdStarter}:{artifactIdStarter}'
}
----
@@ -114,7 +113,7 @@ org.neo4j.driver.authentication.password=secret
This is the bare minimum of what you need to connect to a Neo4j instance.
NOTE: It is not necessary to add any programmatically configuration of the driver when you use this starter.
NOTE: It is not necessary to add any programmatic configuration of the driver when you use this starter.
SDN repositories will be automatically enabled by this starter.
== Create your domain
@@ -127,9 +126,9 @@ Our domain layer should accomplish two things:
=== Example Node-Entity
SDN fully supports unmodifiable entities, for both Java and `data` classes in Kotlin.
Therefor we will focus on immutable entities here, <<movie-entity>> shows a such an entity.
Therefore we will focus on immutable entities here, <<movie-entity>> shows a such an entity.
NOTE: SDN supports all data types the Neo4j Java Driver supports, see https://neo4j.com/docs/driver-manual/current/cypher-values/#driver-neo4j-type-system[Map Neo4j types to native language types] inside the chapter "The Cypher type system".
NOTE: SDN supports all data types the Neo4j Java Driver supports, see https://neo4j.com/docs/driver-manual/current/cypher-workflow/#driver-type-mapping[Map Neo4j types to native language types] inside the chapter "The Cypher type system".
Future versions will support additional converters.
[source,java]
@@ -150,9 +149,9 @@ We also provide generators for UUIDs.
<.> This defines a relationship to a class of type `PersonEntity` and the relationship type `ACTED_IN`
<.> This is the constructor to be used by your application code.
As a general remark: Immutable entities using internally generated ids are a bit contradictory, as SDN needs a way to set the field with the value generated by the database.
As a general remark: immutable entities using internally generated ids are a bit contradictory, as SDN needs a way to set the field with the value generated by the database.
If you don't find a good business key or don't want to use a generator for IDs, here's the same entity using the internally generated id together with a businesses constructor and a so called _wither_-Method, that is used by SDN:
If you don't find a good business key or don't want to use a generator for IDs, here's the same entity using the internally generated id together with a regular constructor and a so called _wither_-Method, that is used by SDN:
[source,java]
[[movie-entity-with-wither]]
@@ -204,7 +203,7 @@ https://projectlombok.org/[Project Lombok] is an alternative if you want or need
=== Declaring Spring Data repositories
You basically have two options here:
You can work store agnostic with SDN and make your domain specific extends one of
you can work in a store-agnostic fashion with SDN and make your domain specific extend one of
* `org.springframework.data.repository.Repository`
* `org.springframework.data.repository.CrudRepository`
@@ -213,11 +212,11 @@ You can work store agnostic with SDN and make your domain specific extends one o
Choose imperative and reactive accordingly.
WARNING: While technically not prohibited, it is not recommended to mix imperative and reactive database access in the same application.
WARNING: While technically not prohibited, it is not recommended mixing imperative and reactive database access in the same application.
We won't support you with scenarios like this.
The other option is to settle on a store specific implementation and gain all the methods we support out of the box.
The advantage of this approach is also it's biggest disadvantage: Once out, all those methods will be part of your API.
The advantage of this approach is also its biggest disadvantage: once out, all those methods will be part of your API.
Most of the time it's harder to take something away, than to add stuff afterwards.
Furthermore, using store specifics leaks your store into your domain.
From a performance point of view, there is no penalty.

View File

@@ -10,7 +10,7 @@ All configuration options of the driver are accessible in the namespace `spring.
The driver bean provides imperative, asynchronous and reactive methods to interact with Neo4j.
You can use all transaction methods the driver provides on that bean such as https://neo4j.com/docs/driver-manual/4.0/terminology/#term-auto-commit[auto-commit transactions],
https://neo4j.com/docs/driver-manual/4.0/terminology/#term-auto-commit[transaction functions] and unmanaged transactions.
https://neo4j.com/docs/driver-manual/4.0/terminology/#term-transaction-function[transaction functions] and unmanaged transactions.
Be aware that those transactions are not tight to an ongoing Spring transaction.
Integration with Spring Data and Spring's platform or reactive transaction manager starts at the <<neo4j-client,Neo4j Client>>.

View File

@@ -1,7 +1,7 @@
[[introduction]]
= Your way through this document
If you already familiar with the core concepts of Spring Data, head straight to <<getting-started>>.
If you are already familiar with the core concepts of Spring Data, head straight to <<getting-started>>.
This chapter will walk you through different options of configuring an application to connect to a Neo4j instance and how to model your domain.
In most cases, you will need a domain.

View File

@@ -1,7 +1,7 @@
[[preface.nosql]]
= NoSQL and Graph databases
A graph database is a storage engine that is specialized in storing and retrieving vast networks of information.
A graph database is a storage engine that specializes in storing and retrieving vast networks of information.
It efficiently stores data as nodes with relationships to other or even the same nodes, thus allowing high-performance retrieval and querying of those structures.
Properties can be added to both nodes and relationships.
Nodes can be labelled by zero or more labels, relationships are always directed and named.
@@ -25,7 +25,6 @@ Here is a list of useful resources:
* The https://neo4j.com/docs/[Neo4j documentation] introduces Neo4j and contains links to getting started guides, reference documentation and tutorials.
* The https://neo4j.com/sandbox/[online sandbox] provides a convenient way to interact with a Neo4j instance in combination with the online https://neo4j.com/developer/get-started/[tutorial].
* Neo4j https://neo4j.com/developer/java/[Java Bolt Driver]
* https://neo4j.com/docs/ogm-manual/current/[Neo4j Object Graph Mapper (OGM) Library]
* Several https://neo4j.com/books/[books] available for purchase and https://www.youtube.com/neo4j[videos] to watch.
[[preface.spring-data]]
@@ -53,7 +52,7 @@ There are a lot of articles, blog entries and books on the matter - take a look
== What is Spring Data Neo4j
The current Spring Data Neo4j is the successor to Spring Data Neo4j + Neo4j-OGM.
The separate layer of Neo4j-OGM (Neo4j Object Graph Mapper) has been replaced by Spring infrastructure, but the basic concepts of an Object Graph Mapper (OGM) still apply:
The separate layer of Neo4j-OGM (Neo4j Object Graph Mapper) has been replaced by Spring infrastructure, but the basic concepts of an Object Graph Mapper (OGM) still apply.
An OGM maps nodes and relationships in the graph to objects and references in a domain model.
Object instances are mapped to nodes while object references are mapped using relationships, or serialized to properties (e.g. references to a Date).
@@ -63,7 +62,7 @@ It also provides the flexibility to the developer to supply custom queries where
=== What's in the box?
Spring Data Neo4j or in short SDN is a next-generation https://spring.io/projects/spring-data[Spring Data] module, created and maintained by https://neo4j.com[Neo4j, Inc.] in close collaboration with https://pivotal.io[Pivotal's] Spring Data Team.
Spring Data Neo4j or in short SDN is a next-generation https://spring.io/projects/spring-data[Spring Data] module, created and maintained by https://neo4j.com[Neo4j, Inc.] in close collaboration with https://www.vmware.com/[VMware's] Spring Data Team.
SDN relies completely on the https://github.com/neo4j/neo4j-java-driver[Neo4j Java Driver], without introducing another "driver" or "transport" layer between the mapping framework and the driver.
The Neo4j Java Driver - sometimes dubbed Bolt or the Bolt driver - is used as a protocol much like JDBC is with relational databases.
@@ -85,11 +84,11 @@ SDN has several features not present in SDN+OGM, notably
=== How does SDN relate to Neo4j-OGM?
https://neo4j.com/docs/ogm-manual/current/[Neo4j-OGM] is an Object Graph Mapping library, which is mainly used by Spring Data Neo4j as its backend for the heavy lifting of mapping nodes and relationships into domain object.
The new SDN *does not need* and *does not support* Neo4j-OGM.
https://neo4j.com/docs/ogm-manual/current/[Neo4j-OGM] is an Object Graph Mapping library, which is mainly used by previous versions of Spring Data Neo4j as its backend for the heavy lifting of mapping nodes and relationships into domain object.
The current SDN *does not need* and *does not support* Neo4j-OGM.
SDN uses Spring Data's mapping context exclusively for scanning classes and building the meta model.
While this pins SDN to the Spring eco systems, it has several advantages, among them the smaller footprint in regards of CPU and memory usage and especially, all the features of Springs mapping context.
While this pins SDN to the Spring ecosystem, it has several advantages, among them the smaller footprint regarding CPU and memory usage and especially, all the features of Spring's mapping context.
=== Does SDN support connections over HTTP to Neo4j?

View File

@@ -163,7 +163,7 @@ In general there is no limitation of relationships / hops for creating the queri
SDN parses the whole reachable graph from your modelled nodes.
This said, when there is the idea of mapping a relationship bidirectional, meaning you define the relationship on both ends of your entity,
you might do not only get what you are expecting.
you might get more than what you are expecting.
Consider an example where a _movie_ has _actors_, and you want to fetch a certain movie with all its actors.
This won't be problematical if the relationship from _movie_ to _actor_ were just unidirectional.
@@ -318,10 +318,10 @@ That leaves the assignment itself:
The generated value will be stable and there wont be a need to change it later on.
* Disadvantage: The generated strategy is applied on the application side of things.
In those days most applications will be deployed in more than one instance to scale nicely.
If your strategy is prone to generate duplicates than inserts will fail as uniques of the primary key will be violated.
If your strategy is prone to generate duplicates then inserts will fail as the uniqueness property of the primary key will be violated.
So while you dont have to think about a unique business key in this scenario, you have to think more what to generate.
You have several options to role your own ID generator.
You have several options to roll out your own ID generator.
One is a POJO implementing a generator:
.Naive sequence generator

View File

@@ -19,17 +19,17 @@ The domain type is the type that has been defined through the repository declara
Interface based projections will always be dynamic proxies to the underlying domain type. The names of the accessors defined
on such interfaces (like `getName`) must resolve to properties (here: `name`) that are present on the projected entity.
Whether those properties have accessors or not on the domain type is not relevant, as long as they can be accessed through
the common Spring Data infrastructure. The later is ensure already, as the domain type wouldn't be a persistent entity in
the common Spring Data infrastructure. The latter is already ensured, as the domain type wouldn't be a persistent entity in
the first place.
DTO based projections are somewhat more flexible when used with custom queries. While the standard query is derived from
the original domain type and therefore only the properties and relationship beeing defined there can be used, custom queries
can add additional properties.
The rules are as follows: First, the properties of the domain type are used to populate the DTO. In case the DTO declare
The rules are as follows: first, the properties of the domain type are used to populate the DTO. In case the DTO declares
additional properties - via accessors or fields - Spring Data Neo4j looks in the resulting record for matching properties.
Properties must match exactly by name and can be of simple types (as defined in `org.springframework.data.neo4j.core.convert.Neo4jSimpleTypes`)
or of known persistent entites. Collections of those are supported, but no maps.
or of known persistent entites. Collections of those are supported, but maps are not.
=== A full example

View File

@@ -208,7 +208,7 @@ Instead, defaulting of properties is handled within the factory method.
* _Try to stick to immutable objects_ --
Immutable objects are straightforward to create as materializing an object is then a matter of calling its constructor only.
Also, this avoids your domain objects to be littered with setter methods that allow client code to manipulate the objects state.
Also, this prevents your domain objects from being littered with setter methods that allow client code to manipulate the objects state.
If you need those, prefer to make them package protected so that they can only be invoked by a limited amount of co-located types.
Constructor-only materialization is up to 30% faster than properties population.
* _Provide an all-args constructor_ --

View File

@@ -3,7 +3,7 @@
== Without Spring Boot
We work a lot with our abstract base classes for configuration in our own integration tests. They can be use like this:
We work a lot with our abstract base classes for configuration in our own integration tests. They can be used like this:
[source,java]
.One possible test setup without Spring Boot
@@ -50,7 +50,7 @@ Similar classes are provided for reactive tests.
== With Spring Boot and `@DataNeo4jTest`
Spring Boot offers `@DataNeo4jTest` through `org.springframework.boot:spring-boot-starter-test`.
The later brings in `org.springframework.boot:spring-boot-test-autoconfigure` which contains the annotion and the
The latter brings in `org.springframework.boot:spring-boot-test-autoconfigure` which contains the annotation and the
required infrastructure code.
[source,xml,subs="verbatim,attributes"]
@@ -63,8 +63,6 @@ required infrastructure code.
</dependency>
----
Or with Gradle
[source,groovy,subs="verbatim,attributes"]
.Include Spring Boot Starter Test in a Gradle build
----
@@ -74,7 +72,7 @@ dependencies {
----
`@DataNeo4jTest` is a Spring Boot https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-testing[test slice].
The test slice provides all the necessary infrastructure for tests using Neo4j: A transaction manager, a client, a template and declared repositories, in their imperative or reactive variants,
The test slice provides all the necessary infrastructure for tests using Neo4j: a transaction manager, a client, a template and declared repositories, in their imperative or reactive variants,
depending on reactive dependencies present or not.
The test slice already includes `@ExtendWith(SpringExtension.class)` so that it runs automatically with JUnit 5 (JUnit Jupiter).
@@ -89,12 +87,12 @@ for the infrastructure to select the correct transaction manager.
The test slice does not bring in an embedded database or any other connection setting.
It is up to you to use an appropriate connection.
We recommend one of two options: Either use the https://www.testcontainers.org/modules/databases/neo4j/[Neo4j Testcontainers module]
We recommend one of two options: either use the https://www.testcontainers.org/modules/databases/neo4j/[Neo4j Testcontainers module]
or the Neo4j test harness.
While Testcontainers is a known project with modules for a lot of different services, Neo4j test harness is rather unknown.
It is an embedded instance that is especially useful when testing stored procedures as described in https://medium.com/neo4j/testing-your-neo4j-based-java-application-34bef487cc3c[Testing your Neo4j-based Java application].
The test harness can however be used to test an application as well.
As it brings up a database inside the same JVM as your application, performance and timings may not reassemble your production setup.
As it brings up a database inside the same JVM as your application, performance and timings may not resemble your production setup.
For your convinience we provide three possible scenarios, Neo4j test harness 3.5 and 4.0 as well as Testcontainers Neo4j.
We provide different examples for 3.5 and 4.0 as the test harness changed between those versions.
@@ -111,7 +109,7 @@ You need the following dependencies to run <<dataneo4jtest-harness35-example>>:
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>3.5.21</version>
<version>3.5.23</version>
<scope>test</scope>
</dependency>
----
@@ -190,7 +188,7 @@ You need the following dependencies to run <<dataneo4jtest-harness40-example>>:
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>4.0.8</version>
<version>{neo4j-version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -261,10 +259,10 @@ class MovieRepositoryTest {
}
----
<.> Entrypoint to create an embedded Neo4j
<.> Don't need Neoj4's HTTP server
<.> Disable the unneeded Neo4j HTTP server
<.> This is a Spring Boot annotation that allows for dynamically registered
application properties. We overwrite the corresponding Neo4j settings.
<.> Shutdown Neo4j after all tests.
<.> Shut down Neo4j after all tests.
[[dataneo4jtest-testcontainers]]
@@ -278,7 +276,7 @@ You need the following dependencies:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>neo4j</artifactId>
<version>1.14.2</version>
<version>1.14.3</version>
<scope>test</scope>
</dependency>
----

View File

@@ -1,7 +1,7 @@
/**
* <!-- tag::intent[] -->
This package contains configuration related support classes that can be used for application specific, annotated
configuration classes. The abstract base classes are helpful if you don't rely on Spring Boots autoconfiguration.
configuration classes. The abstract base classes are helpful if you don't rely on Spring Boot's autoconfiguration.
The package provides some additional annotations that enable auditing.
* <!-- end::intent[] -->
*/