From e8e48d4787133b3c9a491e320fefe6c0f9094e14 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Mon, 25 Sep 2023 14:50:45 +0200 Subject: [PATCH] GH-2797 - Fetch current object's state from property accessor. Before this change, the updated properties where ignored when there was a call to a wither function for property setting. Closes #2797 --- .../core/mapping/DefaultNeo4jEntityConverter.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java b/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java index 0a438cea8..a6ff1ede5 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java @@ -328,7 +328,7 @@ final class DefaultNeo4jEntityConverter implements Neo4jEntityConverter { populateProperties(queryResult, nodeDescription, internalId, instance, lastMappedEntity, relationshipsFromResult, nodesFromResult, false); - PersistentPropertyAccessor propertyAccessor = concreteNodeDescription.getPropertyAccessor(instance); + PersistentPropertyAccessor propertyAccessor = concreteNodeDescription.getPropertyAccessor(getMostCurrentInstance(internalId, instance)); ET bean = propertyAccessor.getBean(); bean = eventSupport.maybeCallAfterConvert(bean, concreteNodeDescription, queryResult); @@ -353,7 +353,13 @@ final class DefaultNeo4jEntityConverter implements Neo4jEntityConverter { // because we cannot just create new instances populateProperties(queryResult, nodeDescription, internalId, mappedObject, lastMappedEntity, relationshipsFromResult, nodesFromResult, true); } - return mappedObject; + // due to a needed side effect in `populateProperties`, the entity might have been changed + return getMostCurrentInstance(internalId, mappedObject); + } + + @Nullable + private ET getMostCurrentInstance(String internalId, ET fallbackInstance) { + return (ET) (knownObjects.getObject(internalId) != null ? knownObjects.getObject(internalId) : fallbackInstance); } @@ -388,7 +394,7 @@ final class DefaultNeo4jEntityConverter implements Neo4jEntityConverter { // in a cyclic graph / with bidirectional relationships, we could end up in a state in which we // reference the start again. Because it is getting still constructed, it won't be in the knownObjects // store unless we temporarily put it there. - knownObjects.storeObject(internalId, mappedObject); + knownObjects.storeObject(internalId, propertyAccessor.getBean()); AssociationHandlerSupport.of(concreteNodeDescription).doWithAssociations( populateFrom(queryResult, nodeDescription, propertyAccessor, isConstructorParameter, objectAlreadyMapped, relationshipsFromResult, nodesFromResult));