Skip to content

Commit 9e2edad

Browse files
fix: Double check for a collection to be present in the mapping without directional prefix.
This is a direct follow up on #2918, in which we added the suffix to the collection names. That change didn’t take custom queries into account and people are most likely still using the known pattern of `source_REL_target` and I would like to not break them. Therefor, we check now in the values list if a collection without suffix exists if we didn’t find one with and if so, use that. This fixes #2963.
1 parent c64d440 commit 9e2edad

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

Diff for: src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java

+5
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,11 @@ private Optional<Object> createInstanceOfRelationships(Neo4jPersistentProperty p
675675
String collectionName = relationshipDescription.generateRelatedNodesCollectionName(baseDescription);
676676
Value list = values.get(collectionName);
677677
boolean relationshipListEmptyOrNull = Values.NULL.equals(list);
678+
if (relationshipListEmptyOrNull) {
679+
collectionName = collectionName.replaceFirst("_" + relationshipDescription.isOutgoing() + "\\z", "");
680+
}
681+
list = values.get(collectionName);
682+
relationshipListEmptyOrNull = Values.NULL.equals(list);
678683

679684
List<Object> relationshipsAndProperties = new ArrayList<>();
680685

Diff for: src/test/java/org/springframework/data/neo4j/integration/issues/IssuesIT.java

+21
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@
187187
import org.springframework.data.neo4j.integration.issues.gh2908.Place;
188188
import org.springframework.data.neo4j.integration.issues.gh2918.ConditionNode;
189189
import org.springframework.data.neo4j.integration.issues.gh2918.ConditionRepository;
190+
import org.springframework.data.neo4j.integration.issues.gh2963.MyModel;
191+
import org.springframework.data.neo4j.integration.issues.gh2963.MyRepository;
190192
import org.springframework.data.neo4j.integration.issues.qbe.A;
191193
import org.springframework.data.neo4j.integration.issues.qbe.ARepository;
192194
import org.springframework.data.neo4j.integration.issues.qbe.B;
@@ -1677,6 +1679,25 @@ void shouldNotGenerateDuplicateOrder(@Autowired LocatedNodeRepository repository
16771679
}
16781680
}
16791681

1682+
@Tag("GH-2963")
1683+
@Test
1684+
void customQueriesShouldKeepWorkingWithoutSpecifyingTheRelDirectionInTheirQueries(@Autowired MyRepository myRepository) {
1685+
// set up data in database
1686+
MyModel myNestedModel = new MyModel();
1687+
myNestedModel.setName("nested");
1688+
1689+
MyModel myRootModel = new MyModel();
1690+
myRootModel.setName("root");
1691+
myRootModel.setMyNestedModel(myNestedModel);
1692+
1693+
String uuid = myRepository.save(myRootModel).getUuid();
1694+
Optional<MyModel> rootModelFromDbCustom = myRepository.getByUuidCustomQuery(uuid);
1695+
assertThat(rootModelFromDbCustom).map(MyModel::getMyNestedModel).isPresent();
1696+
1697+
rootModelFromDbCustom = myRepository.getByUuidCustomQueryV2(uuid);
1698+
assertThat(rootModelFromDbCustom).map(MyModel::getMyNestedModel).isPresent();
1699+
}
1700+
16801701
@Configuration
16811702
@EnableTransactionManagement
16821703
@EnableNeo4jRepositories(namedQueriesLocation = "more-custom-queries.properties")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2011-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2963;
17+
18+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
19+
import org.springframework.data.neo4j.core.schema.Id;
20+
import org.springframework.data.neo4j.core.schema.Node;
21+
import org.springframework.data.neo4j.core.schema.Relationship;
22+
import org.springframework.data.neo4j.core.support.UUIDStringGenerator;
23+
24+
/**
25+
* @author Andreas Rümpel
26+
* @author Michael J. Simons
27+
*/
28+
@Node
29+
public class MyModel {
30+
@Id
31+
@GeneratedValue(generatorClass = UUIDStringGenerator.class)
32+
private String uuid;
33+
34+
private String name;
35+
36+
@Relationship(value = "REL_TO_MY_NESTED_MODEL")
37+
private MyModel myNestedModel;
38+
39+
public MyModel getMyNestedModel() {
40+
return myNestedModel;
41+
}
42+
43+
public void setMyNestedModel(MyModel myNestedModel) {
44+
this.myNestedModel = myNestedModel;
45+
}
46+
47+
public String getName() {
48+
return name;
49+
}
50+
51+
public void setName(String name) {
52+
this.name = name;
53+
}
54+
55+
public String getUuid() {
56+
return uuid;
57+
}
58+
59+
public void setUuid(String uuid) {
60+
this.uuid = uuid;
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2011-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.issues.gh2963;
17+
18+
import java.util.Optional;
19+
20+
import org.springframework.data.neo4j.repository.query.Query;
21+
import org.springframework.data.repository.CrudRepository;
22+
23+
/**
24+
* @author Andreas Rümpel
25+
* @author Michael J. Simons
26+
*/
27+
public interface MyRepository extends CrudRepository<MyModel, String> {
28+
29+
@Query("""
30+
MATCH (root:MyModel {uuid: $uuid})
31+
RETURN root {
32+
.*, MyModel_REL_TO_MY_NESTED_MODEL_MyModel: [
33+
(root)-[:REL_TO_MY_NESTED_MODEL]->(nested:MyModel) | nested {. *}
34+
]
35+
}
36+
""")
37+
Optional<MyModel> getByUuidCustomQuery(String uuid);
38+
39+
@Query("""
40+
MATCH (root:MyModel {uuid: $uuid})
41+
RETURN root {
42+
.*, MyModel_REL_TO_MY_NESTED_MODEL_MyModel_true: [
43+
(root)-[:REL_TO_MY_NESTED_MODEL]->(nested:MyModel) | nested {. *}
44+
]
45+
}
46+
""")
47+
Optional<MyModel> getByUuidCustomQueryV2(String uuid);
48+
}

0 commit comments

Comments
 (0)