GH-2749 - Skip relationship mapping if no relationships are available.

Closes #2749
This commit is contained in:
Gerrit Meier
2023-06-21 15:40:22 +02:00
parent 85d2288b6b
commit 0124f32b7e
3 changed files with 39 additions and 5 deletions

View File

@@ -651,20 +651,26 @@ final class DefaultNeo4jEntityConverter implements Neo4jEntityConverter {
String collectionName = relationshipDescription.generateRelatedNodesCollectionName(genericNodeDescription);
Value list = values.get(collectionName);
boolean relationshipListEmptyOrNull = Values.NULL.equals(list);
List<Object> relationshipsAndProperties = new ArrayList<>();
if (Values.NULL.equals(list)) {
String elementId = IdentitySupport.getElementId(values);
Long internalId = IdentitySupport.getInternalId(values);
boolean hasGeneratedIdValue = elementId != null || internalId != null;
if (relationshipListEmptyOrNull && hasGeneratedIdValue) {
String sourceNodeId;
Function<Relationship, String> sourceIdSelector;
Function<Relationship, String> targetIdSelector = relationshipDescription.isIncoming() ? Relationship::startNodeElementId : Relationship::endNodeElementId;
if (IdentitySupport.getElementId(values) == null) {
if (internalId != null) {
// this can happen when someone used dto mapping and added the "classical" approach
sourceNodeId = Optional.ofNullable(IdentitySupport.getInternalId(values)).map(l -> Long.toString(l)).orElseThrow();
sourceNodeId = Long.toString(internalId);
Function<Relationship, Long> hlp = relationshipDescription.isIncoming() ? Relationship::endNodeId : Relationship::startNodeId;
sourceIdSelector = hlp.andThen(l -> Long.toString(l));
} else {
sourceNodeId = IdentitySupport.getElementId(values);
sourceNodeId = elementId;
sourceIdSelector = relationshipDescription.isIncoming() ? Relationship::endNodeElementId : Relationship::startNodeElementId;
}
@@ -732,7 +738,7 @@ final class DefaultNeo4jEntityConverter implements Neo4jEntityConverter {
}
allMatchingTypeRelationshipsInResult.removeAll(relationshipsProcessed);
}
} else {
} else if (!relationshipListEmptyOrNull) {
for (Value relatedEntity : list.asList(Function.identity())) {
Neo4jPersistentEntity<?> concreteTargetNodeDescription =

View File

@@ -4439,6 +4439,16 @@ class RepositoryIT {
assertThat(repository.findByHobbiesHobbyName("Bowling").getName()).isEqualTo("Freddie");
}
@Test
void findByCustomQueryOnlyWithPropertyReturn(
@Autowired PersonWithRelationshipWithPropertiesRepository repository) {
doWithSession(session ->
session.run(
"CREATE (:PersonWithRelationshipWithProperties{name:'Freddie'})-[:LIKES{since: 2020, active: true}]->(:Hobby{name: 'Bowling'})").consume());
assertThat(repository.justTheNames().getName()).isEqualTo("Freddie");
}
}
@Test // GH-2706
@@ -4526,6 +4536,9 @@ class RepositoryIT {
PersonWithRelationshipWithProperties findByHobbiesSinceAndHobbiesActive(int since1, boolean active);
PersonWithRelationshipWithProperties findByHobbiesHobbyName(String hobbyName);
@Query("MATCH (p:PersonWithRelationshipWithProperties) return p {.name}")
PersonWithRelationshipWithProperties justTheNames();
}
interface PetRepository extends Neo4jRepository<Pet, Long> {

View File

@@ -1572,6 +1572,18 @@ class ReactiveRepositoryIT {
StepVerifier.create(repository.findByHobbiesSinceOrHobbiesActive(2019, false)).verifyComplete();
}
@Test
void findByCustomQueryOnlyWithPropertyReturn(
@Autowired ReactivePersonWithRelationshipWithPropertiesRepository repository) {
doWithSession(session ->
session.run(
"CREATE (:PersonWithRelationshipWithProperties{name:'Freddie'})-[:LIKES{since: 2020, active: true}]->(:Hobby{name: 'Bowling'})").consume()
);
StepVerifier.create(repository.justTheNames())
.assertNext(person -> assertThat(person.getName()).isEqualTo("Freddie")).verifyComplete();
}
@Test
void findByPropertyOnRelationshipWithPropertiesAnd(
@Autowired ReactivePersonWithRelationshipWithPropertiesRepository repository) {
@@ -2744,6 +2756,9 @@ class ReactiveRepositoryIT {
Mono<PersonWithRelationshipWithProperties> findByHobbiesSinceOrHobbiesActive(int since1, boolean active);
Mono<PersonWithRelationshipWithProperties> findByHobbiesSinceAndHobbiesActive(int since1, boolean active);
@Query("MATCH (p:PersonWithRelationshipWithProperties) return p {.name}")
Mono<PersonWithRelationshipWithProperties> justTheNames();
}
interface ReactiveHobbyWithRelationshipWithPropertiesRepository