@@ -171,6 +171,176 @@ The Spring Boot Maven and Gradle plugins do this automatically for you.
171
171
If this is not feasible for any reason, you can either add
172
172
`@Param` and specify the name explicitly or use the parameters index.
173
173
174
+ Mapped entities (everything with a `@Node`) passed as parameter to a function that is annotated with
175
+ a custom query will be turned into a nested map.
176
+ The following example represents the structure as Neo4j parameters.
177
+
178
+ Given are a `Movie`, `Person` and `Actor` classes annotated as shown in <<movie-model, the movie model>>:
179
+
180
+ [[movie-model]]
181
+ [source,java]
182
+ ."Standard" movies model
183
+ ----
184
+ @Node
185
+ public final class Movie {
186
+
187
+ @Id
188
+ private final String title;
189
+
190
+ @Property("tagline")
191
+ private final String description;
192
+
193
+ @Relationship(value = "ACTED_IN", direction = Direction.INCOMING)
194
+ private final List<Actor> actors;
195
+
196
+ @Relationship(value = "DIRECTED", direction = Direction.INCOMING)
197
+ private final List<Person> directors;
198
+ }
199
+
200
+ @Node
201
+ public final class Person {
202
+
203
+ @Id @GeneratedValue
204
+ private final Long id;
205
+
206
+ private final String name;
207
+
208
+ private Integer born;
209
+
210
+ @Relationship("REVIEWED")
211
+ private List<Movie> reviewed = new ArrayList<>();
212
+ }
213
+
214
+ @RelationshipProperties
215
+ public final class Actor {
216
+
217
+ @TargetNode
218
+ private final Person person;
219
+
220
+ private final List<String> roles;
221
+ }
222
+
223
+ interface MovieRepository extends Neo4jRepository<Movie, String> {
224
+
225
+ @Query("MATCH (m:Movie {title: $movie.__id__})\n"
226
+ + "MATCH (m) <- [r:DIRECTED|REVIEWED|ACTED_IN] - (p:Person)\n"
227
+ + "return m, collect(r), collect(p)")
228
+ Movie findByMovie(@Param("movie") Movie movie);
229
+ }
230
+ ----
231
+
232
+ Passing an instance of `Movie` to the repository method above, will generate the following Neo4j map parameter:
233
+
234
+ [source,json]
235
+ ----
236
+ {
237
+ "movie": {
238
+ "__labels__": [
239
+ "Movie"
240
+ ],
241
+ "__id__": "The Da Vinci Code",
242
+ "__properties__": {
243
+ "ACTED_IN": [
244
+ {
245
+ "__properties__": {
246
+ "roles": [
247
+ "Sophie Neveu"
248
+ ]
249
+ },
250
+ "__target__": {
251
+ "__labels__": [
252
+ "Person"
253
+ ],
254
+ "__id__": 402,
255
+ "__properties__": {
256
+ "name": "Audrey Tautou",
257
+ "born": 1976
258
+ }
259
+ }
260
+ },
261
+ {
262
+ "__properties__": {
263
+ "roles": [
264
+ "Sir Leight Teabing"
265
+ ]
266
+ },
267
+ "__target__": {
268
+ "__labels__": [
269
+ "Person"
270
+ ],
271
+ "__id__": 401,
272
+ "__properties__": {
273
+ "name": "Ian McKellen",
274
+ "born": 1939
275
+ }
276
+ }
277
+ },
278
+ {
279
+ "__properties__": {
280
+ "roles": [
281
+ "Dr. Robert Langdon"
282
+ ]
283
+ },
284
+ "__target__": {
285
+ "__labels__": [
286
+ "Person"
287
+ ],
288
+ "__id__": 360,
289
+ "__properties__": {
290
+ "name": "Tom Hanks",
291
+ "born": 1956
292
+ }
293
+ }
294
+ },
295
+ {
296
+ "__properties__": {
297
+ "roles": [
298
+ "Silas"
299
+ ]
300
+ },
301
+ "__target__": {
302
+ "__labels__": [
303
+ "Person"
304
+ ],
305
+ "__id__": 403,
306
+ "__properties__": {
307
+ "name": "Paul Bettany",
308
+ "born": 1971
309
+ }
310
+ }
311
+ }
312
+ ],
313
+ "DIRECTED": [
314
+ {
315
+ "__labels__": [
316
+ "Person"
317
+ ],
318
+ "__id__": 404,
319
+ "__properties__": {
320
+ "name": "Ron Howard",
321
+ "born": 1954
322
+ }
323
+ }
324
+ ],
325
+ "tagline": "Break The Codes",
326
+ "released": 2006
327
+ }
328
+ }
329
+ }
330
+ ----
331
+
332
+ A node is represented by a map. The map will always contain `__id__` which is the mapped id property.
333
+ Under `__labels__` all labels, static and dynamic, will be available.
334
+ All properties - and type of relationships - appear in those maps as they would appear in the graph when the entity would
335
+ have been written by SDN.
336
+ Values will have the correct Cypher type and won't need further conversion.
337
+
338
+ All relationships are lists of maps. Dynamic relationships will be resolved accordingly.
339
+ If an entity has a relationship with the same type to different types of others nodes, they will all appear in the same list.
340
+ If you need such a mapping and also have the need to work with those custom parameters, you have to unroll it accordingly.
341
+ One way to do this are correlated subqueries (Neo4j 4.1+ required).
342
+
343
+
174
344
[[faq.custom-queries]]
175
345
== How do I use custom queries with repository methods returning `Page<T>` or `Slice<T>`?
176
346
0 commit comments