Skip to content

Commit 72b1ecf

Browse files
committed
GH-2749 - Skip relationship mapping if no relationships are available.
Closes #2749
1 parent 6decfa8 commit 72b1ecf

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -651,20 +651,26 @@ private Optional<Object> createInstanceOfRelationships(Neo4jPersistentProperty p
651651
String collectionName = relationshipDescription.generateRelatedNodesCollectionName(genericNodeDescription);
652652

653653
Value list = values.get(collectionName);
654+
boolean relationshipListEmptyOrNull = Values.NULL.equals(list);
654655

655656
List<Object> relationshipsAndProperties = new ArrayList<>();
656657

657-
if (Values.NULL.equals(list)) {
658+
String elementId = IdentitySupport.getElementId(values);
659+
Long internalId = IdentitySupport.getInternalId(values);
660+
boolean hasGeneratedIdValue = elementId != null || internalId != null;
661+
662+
if (relationshipListEmptyOrNull && hasGeneratedIdValue) {
658663
String sourceNodeId;
659664
Function<Relationship, String> sourceIdSelector;
660665
Function<Relationship, String> targetIdSelector = relationshipDescription.isIncoming() ? Relationship::startNodeElementId : Relationship::endNodeElementId;
661-
if (IdentitySupport.getElementId(values) == null) {
666+
667+
if (internalId != null) {
662668
// this can happen when someone used dto mapping and added the "classical" approach
663-
sourceNodeId = Optional.ofNullable(IdentitySupport.getInternalId(values)).map(l -> Long.toString(l)).orElseThrow();
669+
sourceNodeId = Long.toString(internalId);
664670
Function<Relationship, Long> hlp = relationshipDescription.isIncoming() ? Relationship::endNodeId : Relationship::startNodeId;
665671
sourceIdSelector = hlp.andThen(l -> Long.toString(l));
666672
} else {
667-
sourceNodeId = IdentitySupport.getElementId(values);
673+
sourceNodeId = elementId;
668674
sourceIdSelector = relationshipDescription.isIncoming() ? Relationship::endNodeElementId : Relationship::startNodeElementId;
669675
}
670676

@@ -732,7 +738,7 @@ private Optional<Object> createInstanceOfRelationships(Neo4jPersistentProperty p
732738
}
733739
allMatchingTypeRelationshipsInResult.removeAll(relationshipsProcessed);
734740
}
735-
} else {
741+
} else if (!relationshipListEmptyOrNull) {
736742
for (Value relatedEntity : list.asList(Function.identity())) {
737743

738744
Neo4jPersistentEntity<?> concreteTargetNodeDescription =

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4439,6 +4439,16 @@ void findByPropertyOnRelationshipWithPropertiesRelatedEntity(
44394439

44404440
assertThat(repository.findByHobbiesHobbyName("Bowling").getName()).isEqualTo("Freddie");
44414441
}
4442+
4443+
@Test
4444+
void findByCustomQueryOnlyWithPropertyReturn(
4445+
@Autowired PersonWithRelationshipWithPropertiesRepository repository) {
4446+
doWithSession(session ->
4447+
session.run(
4448+
"CREATE (:PersonWithRelationshipWithProperties{name:'Freddie'})-[:LIKES{since: 2020, active: true}]->(:Hobby{name: 'Bowling'})").consume());
4449+
4450+
assertThat(repository.justTheNames().getName()).isEqualTo("Freddie");
4451+
}
44424452
}
44434453

44444454
@Test // GH-2706
@@ -4526,6 +4536,9 @@ interface PersonWithRelationshipWithPropertiesRepository
45264536
PersonWithRelationshipWithProperties findByHobbiesSinceAndHobbiesActive(int since1, boolean active);
45274537

45284538
PersonWithRelationshipWithProperties findByHobbiesHobbyName(String hobbyName);
4539+
4540+
@Query("MATCH (p:PersonWithRelationshipWithProperties) return p {.name}")
4541+
PersonWithRelationshipWithProperties justTheNames();
45294542
}
45304543

45314544
interface PetRepository extends Neo4jRepository<Pet, Long> {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,18 @@ void findByPropertyOnRelationshipWithPropertiesOr(
15721572
StepVerifier.create(repository.findByHobbiesSinceOrHobbiesActive(2019, false)).verifyComplete();
15731573
}
15741574

1575+
@Test
1576+
void findByCustomQueryOnlyWithPropertyReturn(
1577+
@Autowired ReactivePersonWithRelationshipWithPropertiesRepository repository) {
1578+
doWithSession(session ->
1579+
session.run(
1580+
"CREATE (:PersonWithRelationshipWithProperties{name:'Freddie'})-[:LIKES{since: 2020, active: true}]->(:Hobby{name: 'Bowling'})").consume()
1581+
);
1582+
1583+
StepVerifier.create(repository.justTheNames())
1584+
.assertNext(person -> assertThat(person.getName()).isEqualTo("Freddie")).verifyComplete();
1585+
}
1586+
15751587
@Test
15761588
void findByPropertyOnRelationshipWithPropertiesAnd(
15771589
@Autowired ReactivePersonWithRelationshipWithPropertiesRepository repository) {
@@ -2744,6 +2756,9 @@ interface ReactivePersonWithRelationshipWithPropertiesRepository
27442756
Mono<PersonWithRelationshipWithProperties> findByHobbiesSinceOrHobbiesActive(int since1, boolean active);
27452757

27462758
Mono<PersonWithRelationshipWithProperties> findByHobbiesSinceAndHobbiesActive(int since1, boolean active);
2759+
2760+
@Query("MATCH (p:PersonWithRelationshipWithProperties) return p {.name}")
2761+
Mono<PersonWithRelationshipWithProperties> justTheNames();
27472762
}
27482763

27492764
interface ReactiveHobbyWithRelationshipWithPropertiesRepository

0 commit comments

Comments
 (0)