3939import org .neo4j .cypherdsl .core .Conditions ;
4040import org .neo4j .cypherdsl .core .Cypher ;
4141import org .neo4j .cypherdsl .core .Expression ;
42+ import org .neo4j .cypherdsl .core .FunctionInvocation ;
4243import org .neo4j .cypherdsl .core .Functions ;
4344import org .neo4j .cypherdsl .core .MapProjection ;
4445import org .neo4j .cypherdsl .core .Node ;
5455import org .neo4j .cypherdsl .core .SymbolicName ;
5556import org .neo4j .cypherdsl .core .renderer .Configuration ;
5657import org .neo4j .cypherdsl .core .renderer .Renderer ;
58+ import org .neo4j .cypherdsl .core .utils .Assertions ;
5759import org .springframework .data .domain .Sort ;
5860import org .springframework .data .mapping .MappingException ;
5961import org .springframework .data .mapping .PersistentProperty ;
6264import org .springframework .lang .Nullable ;
6365import org .springframework .util .Assert ;
6466
67+ import javax .lang .model .SourceVersion ;
68+
6569/**
6670 * A generator based on the schema defined by node and relationship descriptions. Most methods return renderable Cypher
6771 * statements.
@@ -348,7 +352,7 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
348352 Property versionProperty = rootNode .property (((Neo4jPersistentEntity <?>) nodeDescription ).getRequiredVersionProperty ().getName ());
349353
350354 createIfNew = updateDecorator .apply (optionalMatch (possibleExistingNode )
351- .where (possibleExistingNode . internalId ( ).isEqualTo (idParameter ))
355+ .where (idFunction ( possibleExistingNode ).isEqualTo (idParameter ))
352356 .with (possibleExistingNode )
353357 .where (possibleExistingNode .isNull ())
354358 .create (rootNode .withProperties (versionProperty , literalOf (0 )))
@@ -358,7 +362,7 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
358362 .build ();
359363
360364 updateIfExists = updateDecorator .apply (match (rootNode )
361- .where (rootNode . internalId ( ).isEqualTo (idParameter ))
365+ .where (idFunction ( rootNode ).isEqualTo (idParameter ))
362366 .and (versionProperty .isEqualTo (parameter (Constants .NAME_OF_VERSION_PARAM ))) // Initial check
363367 .set (versionProperty .to (versionProperty .add (literalOf (1 )))) // Acquire lock
364368 .with (rootNode )
@@ -368,19 +372,23 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
368372 .returning (rootNode ).build ();
369373 } else {
370374 createIfNew = updateDecorator
371- .apply (optionalMatch (possibleExistingNode ).where (possibleExistingNode . internalId ( ).isEqualTo (idParameter ))
375+ .apply (optionalMatch (possibleExistingNode ).where (idFunction ( possibleExistingNode ).isEqualTo (idParameter ))
372376 .with (possibleExistingNode ).where (possibleExistingNode .isNull ()).create (rootNode )
373377 .set (rootNode , parameter (Constants .NAME_OF_PROPERTIES_PARAM )))
374378 .returning (rootNode ).build ();
375379
376- updateIfExists = updateDecorator .apply (match (rootNode ).where (rootNode . internalId ( ).isEqualTo (idParameter ))
380+ updateIfExists = updateDecorator .apply (match (rootNode ).where (idFunction ( rootNode ).isEqualTo (idParameter ))
377381 .mutate (rootNode , parameter (Constants .NAME_OF_PROPERTIES_PARAM ))).returning (rootNode ).build ();
378382 }
379383
380384 return Cypher .union (createIfNew , updateIfExists );
381385 }
382386 }
383387
388+ private static FunctionInvocation idFunction (Node rootNode ) {
389+ return Functions .id (rootNode );
390+ }
391+
384392 public Statement prepareSaveOfMultipleInstancesOf (NodeDescription <?> nodeDescription ) {
385393
386394 Assert .isTrue (!nodeDescription .isUsingInternalIds (),
@@ -398,7 +406,7 @@ public Statement prepareSaveOfMultipleInstancesOf(NodeDescription<?> nodeDescrip
398406 return Cypher .unwind (parameter (Constants .NAME_OF_ENTITY_LIST_PARAM )).as (row )
399407 .merge (rootNode .withProperties (nameOfIdProperty , Cypher .property (row , Constants .NAME_OF_ID )))
400408 .mutate (rootNode , Cypher .property (row , Constants .NAME_OF_PROPERTIES_PARAM ))
401- .returning (rootNode . internalId ( ).as (Constants .NAME_OF_INTERNAL_ID ), rootNode .property (nameOfIdProperty ).as (Constants .NAME_OF_ID ))
409+ .returning (idFunction ( rootNode ).as (Constants .NAME_OF_INTERNAL_ID ), rootNode .property (nameOfIdProperty ).as (Constants .NAME_OF_ID ))
402410 .build ();
403411 }
404412
@@ -420,9 +428,9 @@ public Statement prepareSaveOfRelationship(Neo4jPersistentEntity<?> neo4jPersist
420428 startNode .relationshipFrom (endNode , type )).named (RELATIONSHIP_NAME );
421429
422430 return match (startNode )
423- .where (neo4jPersistentEntity .isUsingInternalIds () ? startNode . internalId ( ).isEqualTo (idParameter )
431+ .where (neo4jPersistentEntity .isUsingInternalIds () ? idFunction ( startNode ).isEqualTo (idParameter )
424432 : startNode .property (idPropertyName ).isEqualTo (idParameter ))
425- .match (endNode ).where (endNode . internalId ( ).isEqualTo (parameter (Constants .TO_ID_PARAMETER_NAME )))
433+ .match (endNode ).where (idFunction ( endNode ).isEqualTo (parameter (Constants .TO_ID_PARAMETER_NAME )))
426434 .merge (relationshipFragment )
427435 .returning (Functions .id (relationshipFragment ))
428436 .build ();
@@ -450,9 +458,9 @@ public Statement prepareSaveOfRelationships(Neo4jPersistentEntity<?> neo4jPersis
450458 .with (row )
451459 .match (startNode )
452460 .where (neo4jPersistentEntity .isUsingInternalIds ()
453- ? startNode . internalId ( ).isEqualTo (idProperty )
461+ ? idFunction ( startNode ).isEqualTo (idProperty )
454462 : startNode .property (idPropertyName ).isEqualTo (idProperty ))
455- .match (endNode ).where (endNode . internalId ( ).isEqualTo (Cypher .property (row , Constants .TO_ID_PARAMETER_NAME )))
463+ .match (endNode ).where (idFunction ( endNode ).isEqualTo (Cypher .property (row , Constants .TO_ID_PARAMETER_NAME )))
456464 .merge (relationshipFragment )
457465 .returning (Functions .id (relationshipFragment ))
458466 .build ();
@@ -482,9 +490,9 @@ public Statement prepareSaveOfRelationshipWithProperties(Neo4jPersistentEntity<?
482490 .named (RELATIONSHIP_NAME );
483491
484492 StatementBuilder .OngoingReadingWithWhere startAndEndNodeMatch = match (startNode )
485- .where (neo4jPersistentEntity .isUsingInternalIds () ? startNode . internalId ( ).isEqualTo (idParameter )
493+ .where (neo4jPersistentEntity .isUsingInternalIds () ? idFunction ( startNode ).isEqualTo (idParameter )
486494 : startNode .property (idPropertyName ).isEqualTo (idParameter ))
487- .match (endNode ).where (endNode . internalId ( ).isEqualTo (parameter (Constants .TO_ID_PARAMETER_NAME )));
495+ .match (endNode ).where (idFunction ( endNode ).isEqualTo (parameter (Constants .TO_ID_PARAMETER_NAME )));
488496
489497 StatementBuilder .ExposesSet createOrMatch = isNew
490498 ? startAndEndNodeMatch .create (relationshipFragment )
@@ -527,10 +535,10 @@ public Statement prepareUpdateOfRelationshipsWithProperties(Neo4jPersistentEntit
527535 .match (startNode )
528536 .where (
529537 neo4jPersistentEntity .isUsingInternalIds ()
530- ? startNode . internalId ( ).isEqualTo (idProperty )
538+ ? idFunction ( startNode ).isEqualTo (idProperty )
531539 : startNode .property (idPropertyName ).isEqualTo (idProperty )
532540 )
533- .match (endNode ).where (endNode . internalId ( ).isEqualTo (Cypher .property (row , Constants .TO_ID_PARAMETER_NAME )))
541+ .match (endNode ).where (idFunction ( endNode ).isEqualTo (Cypher .property (row , Constants .TO_ID_PARAMETER_NAME )))
534542 .create (relationshipFragment )
535543 .mutate (RELATIONSHIP_NAME , relationshipProperties )
536544 .returning (Functions .id (relationshipFragment )).build ();
@@ -566,7 +574,7 @@ public Statement prepareDeleteOf(
566574
567575 Parameter <?> idParameter = parameter (Constants .FROM_ID_PARAMETER_NAME );
568576 return match (relationship )
569- .where (neo4jPersistentEntity .isUsingInternalIds () ? startNode . internalId ( ).isEqualTo (idParameter )
577+ .where (neo4jPersistentEntity .isUsingInternalIds () ? idFunction ( startNode ).isEqualTo (idParameter )
570578 : startNode .property (idPropertyName ).isEqualTo (idParameter ))
571579 .and (Functions .id (relationship ).in (Cypher .parameter (Constants .NAME_OF_KNOWN_RELATIONSHIPS_PARAM )).not ())
572580 .delete (relationship .getRequiredSymbolicName ())
@@ -613,6 +621,7 @@ public Collection<Expression> createReturnStatementForMatch(Neo4jPersistentEntit
613621 }
614622 expression = Cypher .property (property .substring (0 , firstDot ), tail );
615623 } else {
624+ Assertions .isTrue (SourceVersion .isIdentifier (property ), "Name must be a valid identifier." );
616625 expression = Cypher .name (property );
617626 }
618627 if (order .isIgnoreCase ()) {
0 commit comments