diff --git a/pom.xml b/pom.xml
index 2e2a2b577f..852ccc3df6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
org.springframework.data
spring-data-neo4j
- 6.0.6-SNAPSHOT
+ 6.0.6-GH-2177-SNAPSHOT
Spring Data Neo4j
Next generation Object-Graph-Mapping for Spring Data.
diff --git a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java
index b4cd3289bc..987491e45e 100644
--- a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java
+++ b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java
@@ -253,7 +253,7 @@ private T saveImpl(T instance, @Nullable String inDatabase) {
propertyAccessor.setProperty(entityMetaData.getRequiredIdProperty(), optionalInternalId.get());
entityToBeSaved = propertyAccessor.getBean();
}
- return processRelations(entityMetaData, entityToBeSaved, isEntityNew, inDatabase);
+ return processRelations(entityMetaData, entityToBeSaved, isEntityNew, inDatabase, instance);
}
private DynamicLabels determineDynamicLabels(T entityToBeSaved, Neo4jPersistentEntity> entityMetaData,
@@ -284,9 +284,9 @@ public List saveAll(Iterable instances) {
String databaseName = getDatabaseName();
- Collection entities;
+ List entities;
if (instances instanceof Collection) {
- entities = (Collection) instances;
+ entities = new ArrayList<>((Collection) instances);
} else {
entities = new ArrayList<>();
instances.forEach(entities::add);
@@ -323,8 +323,11 @@ public List saveAll(Iterable instances) {
.bind(entityList).to(Constants.NAME_OF_ENTITY_LIST_PARAM).run();
// Save related
- entitiesToBeSaved.forEach(entityToBeSaved -> processRelations(entityMetaData, entityToBeSaved,
- isNewIndicator.get(entitiesToBeSaved.indexOf(entityToBeSaved)), databaseName));
+ entitiesToBeSaved.forEach(entityToBeSaved -> {
+ int positionInList = entitiesToBeSaved.indexOf(entityToBeSaved);
+ processRelations(entityMetaData, entityToBeSaved, isNewIndicator.get(positionInList), databaseName,
+ entities.get(positionInList));
+ });
SummaryCounters counters = resultSummary.counters();
log.debug(() -> String.format(
@@ -434,10 +437,10 @@ private ExecutableQuery createExecutableQuery(Class domainType, String
}
private T processRelations(Neo4jPersistentEntity> neo4jPersistentEntity, Object parentObject,
- boolean isParentObjectNew, @Nullable String inDatabase) {
+ boolean isParentObjectNew, @Nullable String inDatabase, Object parentEntity) {
return processNestedRelations(neo4jPersistentEntity, parentObject, isParentObjectNew, inDatabase,
- new NestedRelationshipProcessingStateMachine());
+ new NestedRelationshipProcessingStateMachine(parentEntity));
}
private T processNestedRelations(Neo4jPersistentEntity> sourceEntity, Object parentObject,
@@ -468,7 +471,7 @@ private T processNestedRelations(Neo4jPersistentEntity> sourceEntity, Obje
// break recursive procession and deletion of previously created relationships
ProcessState processState = stateMachine.getStateOf(relationshipDescriptionObverse, relatedValuesToStore);
- if (processState == ProcessState.PROCESSED_ALL_RELATIONSHIPS) {
+ if (processState == ProcessState.PROCESSED_ALL_RELATIONSHIPS || processState == ProcessState.PROCESSED_BOTH) {
return;
}
@@ -517,8 +520,14 @@ private T processNestedRelations(Neo4jPersistentEntity> sourceEntity, Obje
relatedNode = eventSupport.maybeCallBeforeBind(relatedNode);
- Long relatedInternalId = saveRelatedNode(relatedNode, relationshipContext.getAssociationTargetType(),
- targetEntity, inDatabase);
+ Long relatedInternalId;
+ // No need to save values if processed
+ if (processState == ProcessState.PROCESSED_ALL_VALUES) {
+ relatedInternalId = queryRelatedNode(relatedNode, targetEntity, inDatabase);
+ } else {
+ relatedInternalId = saveRelatedNode(relatedNode, relationshipContext.getAssociationTargetType(),
+ targetEntity, inDatabase);
+ }
CreateRelationshipStatementHolder statementHolder = neo4jMappingContext.createStatement(
sourceEntity, relationshipContext, relatedValueToStore);
@@ -553,6 +562,23 @@ private T processNestedRelations(Neo4jPersistentEntity> sourceEntity, Obje
return (T) propertyAccessor.getBean();
}
+ private Long queryRelatedNode(Object entity, Neo4jPersistentEntity> targetNodeDescription,
+ @Nullable String inDatabase) {
+
+ Neo4jPersistentProperty requiredIdProperty = targetNodeDescription.getRequiredIdProperty();
+ PersistentPropertyAccessor