GH-2537 - Improve documentation.

# Conflicts:
#	src/test/java/org/springframework/data/neo4j/integration/issues/IssuesIT.java
#	src/test/java/org/springframework/data/neo4j/integration/issues/gh2323/PersonRepository.java
#	src/test/java/org/springframework/data/neo4j/integration/issues/gh2323/PersonService.java
This commit is contained in:
Michael Simons
2022-06-20 13:12:29 +02:00
parent 8e94651146
commit fb1f05acb8
3 changed files with 46 additions and 1 deletions

View File

@@ -357,7 +357,10 @@ All properties - and type of relationships - appear in those maps as they would
have been written by SDN.
Values will have the correct Cypher type and won't need further conversion.
All relationships are lists of maps. Dynamic relationships will be resolved accordingly.
TIP: All relationships are lists of maps. Dynamic relationships will be resolved accordingly.
One-to-one relationships will also be serialized as singleton lists. So to access a one-to-one mapping
between people, you would write this das `$person.\\__properties__.BEST_FRIEND[0].\\__target__.\\__id__`.
If an entity has a relationship with the same type to different types of others nodes, they will all appear in the same list.
If you need such a mapping and also have the need to work with those custom parameters, you have to unroll it accordingly.
One way to do this are correlated subqueries (Neo4j 4.1+ required).

View File

@@ -18,6 +18,7 @@ package org.springframework.data.neo4j.integration.issues.gh2323;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -65,6 +66,9 @@ class GH2323IT {
.asString();
transaction.run("unwind ['German', 'English'] as name create (n:Language {name: name}) return name")
.consume();
personId = transaction.run("MATCH (l:Language {name: 'German'}) CREATE (n:Person {id: randomUUID(), name: 'Helge'}) -[:HAS_MOTHER_TONGUE]-> (l) return n.id").single()
.get(0)
.asString();
transaction.commit();
bookmarkCapture.seedWith(session.lastBookmark());
}
@@ -105,6 +109,20 @@ class GH2323IT {
});
}
@Test // "GH-2537"
void ensure1To1RelationshipsAreSerialized(@Autowired PersonService personService) {
Optional<Person> optionalPerson = personService.updateRel3(personId);
assertThat(optionalPerson).isPresent().hasValueSatisfying(person -> {
assertThat(person.getKnownLanguages()).hasSize(1);
assertThat(person.getKnownLanguages()).first().satisfies(knows -> {
assertThat(knows.getDescription()).isEqualTo("Whatever");
assertThat(knows.getLanguage()).extracting(Language::getName).isEqualTo("German");
});
});
}
@Repository
public interface PersonRepository extends Neo4jRepository<Person, String> {
@@ -126,6 +144,16 @@ class GH2323IT {
+ "CREATE (f) - [r:KNOWS {description: rel.__properties__.description}] -> (t) "
+ "RETURN f, collect(r), collect(t)")
Person updateRel2(@Param("person") Person person);
@Query(""
+ "MATCH (f:Person {id: $person.__id__}) "
+ "MATCH (mt:Language {name: $person.__properties__.HAS_MOTHER_TONGUE[0].__target__.__id__}) "
+ "MATCH (f)-[frl:HAS_MOTHER_TONGUE]->(mt) WITH f, frl, mt "
+ "UNWIND $person.__properties__.KNOWS As rel WITH f, frl, mt, rel "
+ "MATCH (t:Language {name: rel.__target__.__id__}) "
+ "MERGE (f)- [r:KNOWS {description: rel.__properties__.description}] -> (t) "
+ "RETURN f, frl, mt, collect(r), collect(t)")
Person updateRelWith11(@Param("person") Person person);
}
@Service
@@ -159,6 +187,17 @@ class GH2323IT {
return original;
}
public Optional<Person> updateRel3(String id) {
Optional<Person> original = personRepository.findById(id);
if (original.isPresent()) {
Person person = original.get();
person.setKnownLanguages(Collections.singletonList(new Knows("Whatever", new Language("German"))));
return Optional.of(personRepository.updateRelWith11(person));
}
return original;
}
}
@Configuration

View File

@@ -37,6 +37,9 @@ public class Person {
@Relationship("KNOWS")
private List<Knows> knownLanguages = new ArrayList<>();
@Relationship("HAS_MOTHER_TONGUE")
private Knows motherTongue;
public Person(String name) {
this.name = name;
}