Skip to content

Commit f1518d6

Browse files
DATAGRAPH-1350 - Incoming relationships are not treated correctly when using custom queries.
This change checks the direction of the relationship definition and based on that selects the corresponding target node id. It also uses the property accessor to retrieve the changed instance. Furthermore the opportunity is used for some polishing in the pom.
1 parent 74faebf commit f1518d6

File tree

7 files changed

+173
-9
lines changed

7 files changed

+173
-9
lines changed

pom.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@
6969
</developers>
7070

7171
<properties>
72-
<wurstsalat>ja</wurstsalat>
73-
7472
<apiguardian.version>1.1.0</apiguardian.version>
7573
<asciidoctorj-diagram.version>2.0.1</asciidoctorj-diagram.version>
7674
<asciidoctor-maven-plugin.version>1.6.0</asciidoctor-maven-plugin.version>

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ private <ET> ET map(MapAccessor queryResult, Neo4jPersistentEntity<ET> nodeDescr
282282
concreteNodeDescription.doWithAssociations(
283283
populateFrom(queryResult, propertyAccessor, isConstructorParameter, relationships, knownObjects));
284284
}
285-
return instance;
285+
return propertyAccessor.getBean();
286286
}
287287

288288
/**
@@ -429,11 +429,13 @@ private Optional<Object> createInstanceOfRelationships(Neo4jPersistentProperty p
429429
return Optional.empty();
430430
}
431431

432+
Function<Relationship, Long> targetIdSelector = relationshipDescription.isOutgoing() ? Relationship::endNodeId : Relationship::startNodeId;
433+
432434
for (Node possibleValueNode : allNodesWithMatchingLabelInResult) {
433435
long nodeId = possibleValueNode.id();
434436

435437
for (Relationship possibleRelationship : allMatchingTypeRelationshipsInResult) {
436-
if (possibleRelationship.endNodeId() == nodeId) {
438+
if (targetIdSelector.apply(possibleRelationship) == nodeId) {
437439
Object mappedObject = map(possibleValueNode, concreteTargetNodeDescription, knownObjects);
438440
if (relationshipDescription.hasRelationshipProperties()) {
439441

src/test/java/org/springframework/data/neo4j/documentation/spring_boot/RepositoryIT.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@
4343
import org.testcontainers.junit.jupiter.Container;
4444
import org.testcontainers.junit.jupiter.Testcontainers;
4545

46-
// end::testing.reactivedataneo4jtest[]
47-
// tag::testing.reactivedataneo4jtest[]
48-
// end::testing.reactivedataneo4jtest[]
49-
// tag::testing.reactivedataneo4jtest[]
50-
5146
// end::testing.reactivedataneo4jtest[]
5247

5348
/**

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,27 @@ void loadEntityWithRelationshipWithPropertiesFromCustomQuery(
994994
}).verifyComplete();
995995

996996
}
997+
998+
@Test // DATAGRAPH-1350
999+
void loadEntityWithRelationshipWithPropertiesFromCustomQueryIncoming(
1000+
@Autowired ReactiveHobbyithRelationshipWithPropertiesRepository repository) {
1001+
1002+
long personId;
1003+
1004+
try (Session session = createSession()) {
1005+
Record record = session.run("CREATE (n:AltPerson{name:'Freddie'}), (n)-[l1:LIKES {rating: 5}]->(h1:AltHobby{name:'Music'}) RETURN n, h1").single();
1006+
personId = record.get("n").asNode().id();
1007+
}
1008+
1009+
StepVerifier.create(repository.loadFromCustomQuery(personId)).assertNext(hobby -> {
1010+
assertThat(hobby.getName()).isEqualTo("Music");
1011+
assertThat(hobby.getLikedBy()).hasSize(1);
1012+
assertThat(hobby.getLikedBy().entrySet()).first().satisfies(entry -> {
1013+
assertThat(entry.getKey().getId()).isEqualTo(personId);
1014+
assertThat(entry.getValue().getRating()).isEqualTo(5);
1015+
});
1016+
}).verifyComplete();
1017+
}
9971018
}
9981019

9991020
@Nested
@@ -2053,6 +2074,13 @@ interface ReactivePersonWithRelationshipWithPropertiesRepository
20532074
Mono<PersonWithRelationshipWithProperties> findByHobbiesSinceAndHobbiesActive(int since1, boolean active);
20542075
}
20552076

2077+
interface ReactiveHobbyithRelationshipWithPropertiesRepository
2078+
extends ReactiveNeo4jRepository<AltHobby, Long> {
2079+
2080+
@Query("MATCH (p:AltPerson)-[l:LIKES]->(h:AltHobby) WHERE id(p) = $personId RETURN h, collect(l), collect(p)")
2081+
Flux<AltHobby> loadFromCustomQuery(@Param("personId") Long personId);
2082+
}
2083+
20562084
interface ReactivePetRepository extends ReactiveNeo4jRepository<Pet, Long> {}
20572085

20582086
interface ReactiveRelationshipRepository extends ReactiveNeo4jRepository<PersonWithRelationship, Long> {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2011-2020 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.shared;
17+
18+
import static org.springframework.data.neo4j.core.schema.Relationship.Direction.*;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
24+
import org.springframework.data.neo4j.core.schema.Id;
25+
import org.springframework.data.neo4j.core.schema.Node;
26+
import org.springframework.data.neo4j.core.schema.Relationship;
27+
28+
/**
29+
* @@author Michael J. Simons
30+
*/
31+
@Node
32+
public class AltHobby {
33+
@Id @GeneratedValue private Long id;
34+
35+
private String name;
36+
37+
@Relationship(type = "LIKES", direction = INCOMING)
38+
private Map<AltPerson, AltLikedByPersonRelationship> likedBy = new HashMap<>();
39+
40+
public Long getId() {
41+
return id;
42+
}
43+
44+
public void setId(Long id) {
45+
this.id = id;
46+
}
47+
48+
public String getName() {
49+
return name;
50+
}
51+
52+
public void setName(String name) {
53+
this.name = name;
54+
}
55+
56+
public Map<AltPerson, AltLikedByPersonRelationship> getLikedBy() {
57+
return likedBy;
58+
}
59+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2011-2020 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.shared;
17+
18+
import org.springframework.data.neo4j.core.schema.RelationshipProperties;
19+
20+
/**
21+
* @@author Michael J. Simons
22+
*/
23+
@RelationshipProperties
24+
public class AltLikedByPersonRelationship {
25+
26+
private Integer rating;
27+
28+
public Integer getRating() {
29+
return rating;
30+
}
31+
32+
public void setRating(Integer rating) {
33+
this.rating = rating;
34+
}
35+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2011-2020 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.shared;
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+
22+
/**
23+
* @@author Michael J. Simons
24+
*/
25+
@Node
26+
public class AltPerson {
27+
28+
@Id @GeneratedValue private Long id;
29+
30+
private final String name;
31+
32+
public AltPerson(String name) {
33+
this.name = name;
34+
}
35+
36+
public Long getId() {
37+
return id;
38+
}
39+
40+
public void setId(Long id) {
41+
this.id = id;
42+
}
43+
44+
public String getName() {
45+
return name;
46+
}
47+
}

0 commit comments

Comments
 (0)