@@ -249,7 +249,7 @@ private <T> Mono<T> saveImpl(T instance, @Nullable String inDatabase) {
249
249
}));
250
250
251
251
if (!entityMetaData .isUsingInternalIds ()) {
252
- return idMono .then (processRelations (entityMetaData , entity , isNewEntity , inDatabase ))
252
+ return idMono .then (processRelations (entityMetaData , entity , isNewEntity , inDatabase , instance ))
253
253
.thenReturn (entity );
254
254
} else {
255
255
return idMono .map (internalId -> {
@@ -258,7 +258,7 @@ private <T> Mono<T> saveImpl(T instance, @Nullable String inDatabase) {
258
258
259
259
return propertyAccessor .getBean ();
260
260
}).flatMap (
261
- savedEntity -> processRelations (entityMetaData , savedEntity , isNewEntity , inDatabase )
261
+ savedEntity -> processRelations (entityMetaData , savedEntity , isNewEntity , inDatabase , instance )
262
262
.thenReturn (savedEntity ));
263
263
}
264
264
}));
@@ -290,9 +290,9 @@ private <T> Mono<Tuple2<T, DynamicLabels>> determineDynamicLabels(T entityToBeSa
290
290
@ Override
291
291
public <T > Flux <T > saveAll (Iterable <T > instances ) {
292
292
293
- Collection <T > entities ;
293
+ List <T > entities ;
294
294
if (instances instanceof Collection ) {
295
- entities = ( Collection <T >) instances ;
295
+ entities = new ArrayList <>(( Collection <T >) instances ) ;
296
296
} else {
297
297
entities = new ArrayList <>();
298
298
instances .forEach (entities ::add );
@@ -338,7 +338,7 @@ public <T> Flux<T> saveAll(Iterable<T> instances) {
338
338
T entityToBeSaved = t .getT2 ();
339
339
boolean isNew = isNewIndicator .get (Math .toIntExact (t .getT1 ()));
340
340
return processRelations (entityMetaData , entityToBeSaved , isNew ,
341
- databaseName .getValue ())
341
+ databaseName .getValue (), entities . get ( Math . toIntExact ( t . getT1 ())) )
342
342
.then (Mono .just (entityToBeSaved ));
343
343
}
344
344
);
@@ -566,10 +566,10 @@ Publisher<Tuple2<Collection<Long>, Collection<Long>>>> iterateAndMapNextLevel(
566
566
}
567
567
568
568
private Mono <Void > processRelations (Neo4jPersistentEntity <?> neo4jPersistentEntity , Object parentObject ,
569
- boolean isParentObjectNew , @ Nullable String inDatabase ) {
569
+ boolean isParentObjectNew , @ Nullable String inDatabase , Object parentEntity ) {
570
570
571
571
return processNestedRelations (neo4jPersistentEntity , parentObject , isParentObjectNew , inDatabase ,
572
- new NestedRelationshipProcessingStateMachine ());
572
+ new NestedRelationshipProcessingStateMachine (parentEntity ));
573
573
}
574
574
575
575
private Mono <Void > processNestedRelations (Neo4jPersistentEntity <?> sourceEntity , Object parentObject ,
@@ -602,7 +602,7 @@ private Mono<Void> processNestedRelations(Neo4jPersistentEntity<?> sourceEntity,
602
602
603
603
// break recursive procession and deletion of previously created relationships
604
604
ProcessState processState = stateMachine .getStateOf (relationshipDescriptionObverse , relatedValuesToStore );
605
- if (processState == ProcessState .PROCESSED_ALL_RELATIONSHIPS ) {
605
+ if (processState == ProcessState .PROCESSED_ALL_RELATIONSHIPS || processState == ProcessState . PROCESSED_BOTH ) {
606
606
return ;
607
607
}
608
608
@@ -652,9 +652,16 @@ private Mono<Void> processNestedRelations(Neo4jPersistentEntity<?> sourceEntity,
652
652
.flatMap (relatedNode -> {
653
653
Neo4jPersistentEntity <?> targetEntity = neo4jMappingContext
654
654
.getPersistentEntity (relatedNodePreEvt .getClass ());
655
- return Mono .just (targetEntity .isNew (relatedNode )).flatMap (isNew ->
656
- saveRelatedNode (relatedNode , relationshipContext .getAssociationTargetType (),
657
- targetEntity , inDatabase ).flatMap (relatedInternalId -> {
655
+ return Mono .just (targetEntity .isNew (relatedNode )).flatMap (isNew -> {
656
+ Mono <Long > relatedIdMono ;
657
+
658
+ if (processState == ProcessState .PROCESSED_ALL_VALUES ) {
659
+ relatedIdMono = queryRelatedNode (relatedNode , targetEntity , inDatabase );
660
+ } else {
661
+ relatedIdMono = saveRelatedNode (relatedNode , relationshipContext .getAssociationTargetType (),
662
+ targetEntity , inDatabase );
663
+ }
664
+ return relatedIdMono .flatMap (relatedInternalId -> {
658
665
659
666
// if an internal id is used this must get set to link this entity in the next iteration
660
667
PersistentPropertyAccessor <?> targetPropertyAccessor = targetEntity
@@ -691,7 +698,8 @@ private Mono<Void> processNestedRelations(Neo4jPersistentEntity<?> sourceEntity,
691
698
} else {
692
699
return relationshipCreationMonoNested .checkpoint ().then ();
693
700
}
694
- }).checkpoint ());
701
+ }).checkpoint ();
702
+ });
695
703
});
696
704
relationshipCreationMonos .add (createRelationship );
697
705
}
@@ -701,6 +709,23 @@ private Mono<Void> processNestedRelations(Neo4jPersistentEntity<?> sourceEntity,
701
709
});
702
710
}
703
711
712
+ private <Y > Mono <Long > queryRelatedNode (Object entity , Neo4jPersistentEntity <?> targetNodeDescription ,
713
+ @ Nullable String inDatabase ) {
714
+
715
+ Neo4jPersistentProperty requiredIdProperty = targetNodeDescription .getRequiredIdProperty ();
716
+ PersistentPropertyAccessor <Object > targetPropertyAccessor = targetNodeDescription .getPropertyAccessor (entity );
717
+ Object idValue = targetPropertyAccessor .getProperty (requiredIdProperty );
718
+
719
+ return neo4jClient .query (() ->
720
+ renderer .render (cypherGenerator .prepareMatchOf (targetNodeDescription ,
721
+ targetNodeDescription .getIdExpression ().isEqualTo (parameter (Constants .NAME_OF_ID )))
722
+ .returning (Constants .NAME_OF_INTERNAL_ID )
723
+ .build ())
724
+ )
725
+ .in (inDatabase ).bindAll (Collections .singletonMap (Constants .NAME_OF_ID , idValue ))
726
+ .fetchAs (Long .class ).one ();
727
+ }
728
+
704
729
private <Y > Mono <Long > saveRelatedNode (Object relatedNode , Class <Y > entityType , NodeDescription targetNodeDescription ,
705
730
@ Nullable String inDatabase ) {
706
731
0 commit comments