Skip to content

Commit ec5cb85

Browse files
committed
GH-2668 - Optimise update of relationship properties.
There is no need to fetch start and end node if we already have the identifier of the relationship to update. Closes #2668
1 parent 56fb58b commit ec5cb85

File tree

5 files changed

+28
-24
lines changed

5 files changed

+28
-24
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java

+18-14
Original file line numberDiff line numberDiff line change
@@ -518,24 +518,28 @@ public Statement prepareUpdateOfRelationshipsWithProperties(Neo4jPersistentEntit
518518
String row = "row";
519519
Property relationshipProperties = Cypher.property(row, Constants.NAME_OF_PROPERTIES_PARAM);
520520
Property idProperty = Cypher.property(row, Constants.FROM_ID_PARAMETER_NAME);
521-
StatementBuilder.OngoingReadingWithWhere matchStartAndEndNode =
522-
Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM)).as(row)
523-
.with(row)
524-
.match(startNode)
525-
.where(neo4jPersistentEntity.isUsingInternalIds() ? startNode.internalId().isEqualTo(idProperty)
526-
: startNode.property(idPropertyName).isEqualTo(idProperty))
527-
.match(endNode).where(endNode.internalId().isEqualTo(Cypher.property(row, Constants.TO_ID_PARAMETER_NAME)));
528521

529-
StatementBuilder.ExposesSet createOrUpdateRelationship = isNew
530-
? matchStartAndEndNode.create(relationshipFragment)
531-
: matchStartAndEndNode.match(relationshipFragment)
532-
.where(Functions.id(relationshipFragment).isEqualTo(Cypher.property(row, Constants.NAME_OF_KNOWN_RELATIONSHIP_PARAM)));
522+
StatementBuilder.OrderableOngoingReadingAndWithWithoutWhere relationshipUnwind = Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM))
523+
.as(row).with(row);
533524

534525
if (isNew) {
535-
return createOrUpdateRelationship.mutate(RELATIONSHIP_NAME, relationshipProperties).returning(Functions.id(relationshipFragment)).build();
526+
return relationshipUnwind
527+
.match(startNode)
528+
.where(
529+
neo4jPersistentEntity.isUsingInternalIds()
530+
? startNode.internalId().isEqualTo(idProperty)
531+
: startNode.property(idPropertyName).isEqualTo(idProperty)
532+
)
533+
.match(endNode).where(endNode.internalId().isEqualTo(Cypher.property(row, Constants.TO_ID_PARAMETER_NAME)))
534+
.create(relationshipFragment)
535+
.mutate(RELATIONSHIP_NAME, relationshipProperties)
536+
.returning(Functions.id(relationshipFragment)).build();
537+
} else {
538+
return relationshipUnwind
539+
.match(relationshipFragment)
540+
.where(Functions.id(relationshipFragment).isEqualTo(Cypher.property(row, Constants.NAME_OF_KNOWN_RELATIONSHIP_PARAM)))
541+
.mutate(RELATIONSHIP_NAME, relationshipProperties).build();
536542
}
537-
538-
return createOrUpdateRelationship.mutate(RELATIONSHIP_NAME, relationshipProperties).build();
539543
}
540544

541545
@NonNull

src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryWithADifferentDatabaseIT.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static void createTestDatabase() {
3838

3939
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
4040

41-
session.run("CREATE DATABASE " + TEST_DATABASE_NAME).consume();
41+
session.run("CREATE DATABASE " + TEST_DATABASE_NAME + " IF NOT EXISTS").consume();
4242
}
4343

4444
databaseSelection.set(DatabaseSelection.byName(TEST_DATABASE_NAME));
@@ -49,7 +49,7 @@ static void dropTestDatabase() {
4949

5050
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
5151

52-
session.run("DROP DATABASE " + TEST_DATABASE_NAME).consume();
52+
session.run("DROP DATABASE " + TEST_DATABASE_NAME + " IF EXISTS").consume();
5353
}
5454

5555
databaseSelection.set(DatabaseSelection.undecided());

src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryWithADifferentUserIT.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ static void createTestDatabase() {
4545

4646
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
4747

48-
session.run("CREATE DATABASE $db", Values.parameters("db", TEST_DATABASE_NAME)).consume();
48+
session.run("CREATE DATABASE $db IF NOT EXISTS", Values.parameters("db", TEST_DATABASE_NAME)).consume();
4949
session.run("CREATE USER $user SET PASSWORD $password CHANGE NOT REQUIRED SET HOME DATABASE $database",
50-
Values.parameters("user", TEST_USER, "password", TEST_USER, "database", TEST_DATABASE_NAME))
50+
Values.parameters("user", TEST_USER, "password", TEST_USER + TEST_USER, "database", TEST_DATABASE_NAME))
5151
.consume();
5252
session.run("GRANT ROLE publisher TO $user", Values.parameters("user", TEST_USER)).consume();
5353
session.run("GRANT IMPERSONATE ($targetUser) ON DBMS TO admin", Values.parameters("targetUser", TEST_USER))
@@ -65,7 +65,7 @@ static void dropTestDatabase() {
6565
session.run("REVOKE IMPERSONATE ($targetUser) ON DBMS FROM admin",
6666
Values.parameters("targetUser", TEST_USER)).consume();
6767
session.run("DROP USER $user", Values.parameters("user", TEST_USER)).consume();
68-
session.run("DROP DATABASE $db", Values.parameters("db", TEST_DATABASE_NAME)).consume();
68+
session.run("DROP DATABASE $db IF EXISTS", Values.parameters("db", TEST_DATABASE_NAME)).consume();
6969
}
7070

7171
userSelection.set(UserSelection.connectedUser());

src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveRepositoryWithADifferentDatabaseIT.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static void createTestDatabase() {
3838

3939
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
4040

41-
session.run("CREATE DATABASE " + TEST_DATABASE_NAME).consume();
41+
session.run("CREATE DATABASE " + TEST_DATABASE_NAME + " IF NOT EXISTS").consume();
4242
}
4343

4444
databaseSelection.set(DatabaseSelection.byName(TEST_DATABASE_NAME));
@@ -49,7 +49,7 @@ static void dropTestDatabase() {
4949

5050
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
5151

52-
session.run("DROP DATABASE " + TEST_DATABASE_NAME).consume();
52+
session.run("DROP DATABASE " + TEST_DATABASE_NAME + " IF EXISTS").consume();
5353
}
5454

5555
databaseSelection.set(DatabaseSelection.undecided());

src/test/java/org/springframework/data/neo4j/integration/reactive/ReactiveRepositoryWithADifferentUserIT.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ static void createTestDatabase() {
4545

4646
try (Session session = neo4jConnectionSupport.getDriver().session(SessionConfig.forDatabase("system"))) {
4747

48-
session.run("CREATE DATABASE $db", Values.parameters("db", TEST_DATABASE_NAME)).consume();
48+
session.run("CREATE DATABASE $db IF NOT EXISTS", Values.parameters("db", TEST_DATABASE_NAME)).consume();
4949
session.run("CREATE USER $user SET PASSWORD $password CHANGE NOT REQUIRED SET HOME DATABASE $database",
50-
Values.parameters("user", TEST_USER, "password", TEST_USER, "database", TEST_DATABASE_NAME))
50+
Values.parameters("user", TEST_USER, "password", TEST_USER + TEST_USER, "database", TEST_DATABASE_NAME))
5151
.consume();
5252
session.run("GRANT ROLE publisher TO $user", Values.parameters("user", TEST_USER)).consume();
5353
session.run("GRANT IMPERSONATE ($targetUser) ON DBMS TO admin", Values.parameters("targetUser", TEST_USER))
@@ -65,7 +65,7 @@ static void dropTestDatabase() {
6565
session.run("REVOKE IMPERSONATE ($targetUser) ON DBMS FROM admin",
6666
Values.parameters("targetUser", TEST_USER)).consume();
6767
session.run("DROP USER $user", Values.parameters("user", TEST_USER)).consume();
68-
session.run("DROP DATABASE $db", Values.parameters("db", TEST_DATABASE_NAME)).consume();
68+
session.run("DROP DATABASE $db IF EXISTS", Values.parameters("db", TEST_DATABASE_NAME)).consume();
6969
}
7070

7171
userSelection.set(UserSelection.connectedUser());

0 commit comments

Comments
 (0)