1919
2020import java .util .Arrays ;
2121import java .util .List ;
22+ import java .util .Optional ;
2223import java .util .stream .Collectors ;
2324
2425import org .junit .jupiter .api .BeforeAll ;
26+ import org .junit .jupiter .api .BeforeEach ;
2527import org .junit .jupiter .api .Test ;
2628import org .neo4j .driver .Driver ;
2729import org .neo4j .driver .Session ;
3032import org .springframework .context .annotation .Bean ;
3133import org .springframework .context .annotation .ComponentScan ;
3234import org .springframework .context .annotation .Configuration ;
33- import org .springframework .data .neo4j .test .Neo4jImperativeTestConfiguration ;
3435import org .springframework .data .neo4j .repository .Neo4jRepository ;
3536import org .springframework .data .neo4j .repository .config .EnableNeo4jRepositories ;
3637import org .springframework .data .neo4j .repository .query .Query ;
3738import org .springframework .data .neo4j .test .BookmarkCapture ;
3839import org .springframework .data .neo4j .test .Neo4jExtension ;
40+ import org .springframework .data .neo4j .test .Neo4jImperativeTestConfiguration ;
3941import org .springframework .data .neo4j .test .Neo4jIntegrationTest ;
4042import org .springframework .data .repository .query .Param ;
4143import org .springframework .stereotype .Repository ;
@@ -68,6 +70,17 @@ protected static void setupData(@Autowired BookmarkCapture bookmarkCapture) {
6870 }
6971 }
7072
73+ @ BeforeEach
74+ protected void removeRelationships (@ Autowired BookmarkCapture bookmarkCapture ) {
75+ try (Session session = neo4jConnectionSupport .getDriver ().session (bookmarkCapture .createSessionConfig ());
76+ Transaction transaction = session .beginTransaction ();
77+ ) {
78+ transaction .run ("MATCH ()- [r:KNOWS]-() delete r" ).consume ();
79+ transaction .commit ();
80+ bookmarkCapture .seedWith (session .lastBookmark ());
81+ }
82+ }
83+
7184 @ Test // GH-2323
7285 void listOfRelationshipPropertiesShouldBeUnwindable (@ Autowired PersonService personService ) {
7386 Person person = personService .updateRel (personId , Arrays .asList ("German" ));
@@ -79,14 +92,43 @@ void listOfRelationshipPropertiesShouldBeUnwindable(@Autowired PersonService per
7992 });
8093 }
8194
95+ @ Test // GH-2537
96+ void ensureRelationshipsAreSerialized (@ Autowired PersonService personService ) {
97+
98+ Optional <Person > optionalPerson = personService .updateRel2 (personId , Arrays .asList ("German" ));
99+ assertThat (optionalPerson ).isPresent ().hasValueSatisfying (person -> {
100+ assertThat (person .getKnownLanguages ()).hasSize (1 );
101+ assertThat (person .getKnownLanguages ()).first ().satisfies (knows -> {
102+ assertThat (knows .getDescription ()).isEqualTo ("Some description" );
103+ assertThat (knows .getLanguage ()).extracting (Language ::getName ).isEqualTo ("German" );
104+ });
105+ });
106+ }
107+
82108 @ Repository
83109 public interface PersonRepository extends Neo4jRepository <Person , String > {
84110
85- @ Query ("UNWIND $relations As rel WITH rel " +
86- "CREATE (f:Person {id: $from}) - [r:KNOWS {description: rel.__properties__.description}] -> (t:Language {name: rel.__properties__.__target__.__id__}) "
87- +
88- "RETURN f, collect(r), collect(t)" )
111+ // Using separate id and than relationships on top level
112+ @ Query ("""
113+ UNWIND $relations As rel WITH rel
114+ MATCH (f:Person {id: $from})
115+ MATCH (t:Language {name: rel.__target__.__id__})
116+ CREATE (f)- [r:KNOWS {description: rel.__properties__.description}] -> (t)
117+ RETURN f, collect(r), collect(t)
118+ """
119+ )
89120 Person updateRel (@ Param ("from" ) String from , @ Param ("relations" ) List <Knows > relations );
121+
122+ // Using the whole person object
123+ @ Query ("""
124+ UNWIND $person.__properties__.KNOWS As rel WITH rel
125+ MATCH (f:Person {id: $person.__id__})
126+ MATCH (t:Language {name: rel.__target__.__id__})
127+ CREATE (f) - [r:KNOWS {description: rel.__properties__.description}] -> (t)
128+ RETURN f, collect(r), collect(t)
129+ """
130+ )
131+ Person updateRel2 (@ Param ("person" ) Person person );
90132 }
91133
92134 @ Service
@@ -105,6 +147,21 @@ public Person updateRel(String from, List<String> languageNames) {
105147 .collect (Collectors .toList ());
106148 return personRepository .updateRel (from , knownLanguages );
107149 }
150+
151+ public Optional <Person > updateRel2 (String id , List <String > languageNames ) {
152+
153+ Optional <Person > original = personRepository .findById (id );
154+ if (original .isPresent ()) {
155+ Person person = original .get ();
156+ List <Knows > knownLanguages = languageNames .stream ().map (Language ::new )
157+ .map (language -> new Knows ("Some description" , language ))
158+ .collect (Collectors .toList ());
159+ person .setKnownLanguages (knownLanguages );
160+ return Optional .of (personRepository .updateRel2 (person ));
161+ }
162+
163+ return original ;
164+ }
108165 }
109166
110167 @ Configuration
0 commit comments