@@ -1195,8 +1195,8 @@ private NodesAndRelationshipsByIdStatementProvider createNodesAndRelationshipsBy
1195
1195
return NodesAndRelationshipsByIdStatementProvider .EMPTY ;
1196
1196
}
1197
1197
// load first level relationships
1198
- final Set <String > relationshipIds = new HashSet <>();
1199
- final Set <String > relatedNodeIds = new HashSet <>();
1198
+ // final Set<String> relationshipIds = new HashSet<>();
1199
+ final Map < String , Set <String >> relationshipsToRelatedNodeIds = new HashMap <>();
1200
1200
1201
1201
for (RelationshipDescription relationshipDescription : entityMetaData .getRelationshipsInHierarchy (queryFragments ::includeField )) {
1202
1202
@@ -1210,14 +1210,14 @@ private NodesAndRelationshipsByIdStatementProvider createNodesAndRelationshipsBy
1210
1210
.bindAll (usedParameters )
1211
1211
.fetch ()
1212
1212
.one ()
1213
- .ifPresent (iterateAndMapNextLevel (relationshipIds , relatedNodeIds , relationshipDescription , PropertyPathWalkStep .empty ()));
1213
+ .ifPresent (iterateAndMapNextLevel (relationshipsToRelatedNodeIds , relationshipDescription , PropertyPathWalkStep .empty ()));
1214
1214
}
1215
1215
1216
- return new NodesAndRelationshipsByIdStatementProvider (rootNodeIds , relationshipIds , relatedNodeIds , queryFragments , elementIdOrIdFunction );
1216
+ return new NodesAndRelationshipsByIdStatementProvider (rootNodeIds , relationshipsToRelatedNodeIds . keySet (), relationshipsToRelatedNodeIds . values (). stream (). flatMap ( Collection :: stream ). toList () , queryFragments , elementIdOrIdFunction );
1217
1217
}
1218
1218
1219
- private void iterateNextLevel (Collection <String > nodeIds , RelationshipDescription sourceRelationshipDescription , Set < String > relationshipIds ,
1220
- Set <String > relatedNodeIds , PropertyPathWalkStep currentPathStep ) {
1219
+ private void iterateNextLevel (Collection <String > nodeIds , RelationshipDescription sourceRelationshipDescription ,
1220
+ Map < String , Set <String >> relationshipsToRelatedNodes , PropertyPathWalkStep currentPathStep ) {
1221
1221
1222
1222
Neo4jPersistentEntity <?> target = (Neo4jPersistentEntity <?>) sourceRelationshipDescription .getTarget ();
1223
1223
@@ -1251,32 +1251,42 @@ private void iterateNextLevel(Collection<String> nodeIds, RelationshipDescriptio
1251
1251
.bindAll (Collections .singletonMap (Constants .NAME_OF_IDS , TemplateSupport .convertToLongIdOrStringElementId (nodeIds )))
1252
1252
.fetch ()
1253
1253
.one ()
1254
- .ifPresent (iterateAndMapNextLevel (relationshipIds , relatedNodeIds , relationshipDescription , nextPathStep ));
1254
+ .ifPresent (iterateAndMapNextLevel (relationshipsToRelatedNodes , relationshipDescription , nextPathStep ));
1255
1255
}
1256
1256
}
1257
1257
1258
1258
@ NonNull
1259
- private Consumer <Map <String , Object >> iterateAndMapNextLevel (Set <String > relationshipIds ,
1260
- Set <String > relatedNodeIds ,
1259
+ private Consumer <Map <String , Object >> iterateAndMapNextLevel (Map <String , Set <String >> relationshipsToRelatedNodes ,
1261
1260
RelationshipDescription relationshipDescription ,
1262
1261
PropertyPathWalkStep currentPathStep ) {
1263
1262
1264
1263
return record -> {
1264
+
1265
+ Map <String , Set <String >> relatedNodesVisited = new HashMap <>(relationshipsToRelatedNodes );
1265
1266
@ SuppressWarnings ("unchecked" )
1266
1267
List <String > newRelationshipIds = ((List <Object >) record .get (Constants .NAME_OF_SYNTHESIZED_RELATIONS )).stream ().map (TemplateSupport ::convertIdOrElementIdToString ).toList ();
1267
- relationshipIds .addAll (newRelationshipIds );
1268
-
1269
1268
@ SuppressWarnings ("unchecked" )
1270
- List <String > newRelatedNodeIds = (( List <Object >) record .get (Constants .NAME_OF_SYNTHESIZED_RELATED_NODES )).stream ().map (TemplateSupport ::convertIdOrElementIdToString ).toList ();
1269
+ Set <String > relatedIds = new HashSet <>((( List <Object >) record .get (Constants .NAME_OF_SYNTHESIZED_RELATED_NODES )).stream ().map (TemplateSupport ::convertIdOrElementIdToString ).toList () );
1271
1270
1272
- Set <String > relatedIds = new HashSet <>(newRelatedNodeIds );
1273
1271
// use this list to get down the road
1274
1272
// 1. remove already visited ones;
1275
- relatedIds .removeAll (relatedNodeIds );
1276
- relatedNodeIds .addAll (relatedIds );
1273
+ // we don't know which id came with which node, so we need to assume that a relationshipId connects to all related nodes
1274
+ for (String newRelationshipId : newRelationshipIds ) {
1275
+ relatedNodesVisited .put (newRelationshipId , relatedIds );
1276
+ Set <String > knownRelatedNodesBefore = relationshipsToRelatedNodes .get (newRelationshipId );
1277
+ if (knownRelatedNodesBefore != null ) {
1278
+ Set <String > mergedKnownRelatedNodes = new HashSet <>(knownRelatedNodesBefore );
1279
+ // there are already existing nodes in there for this relationship
1280
+ mergedKnownRelatedNodes .addAll (relatedIds );
1281
+ relatedNodesVisited .put (newRelationshipId , mergedKnownRelatedNodes );
1282
+ relatedIds .removeAll (knownRelatedNodesBefore );
1283
+ }
1284
+ }
1285
+
1286
+ relationshipsToRelatedNodes .putAll (relatedNodesVisited );
1277
1287
// 2. for the rest start the exploration
1278
1288
if (!relatedIds .isEmpty ()) {
1279
- iterateNextLevel (relatedIds , relationshipDescription , relationshipIds , relatedNodeIds , currentPathStep );
1289
+ iterateNextLevel (relatedIds , relationshipDescription , relationshipsToRelatedNodes , currentPathStep );
1280
1290
}
1281
1291
};
1282
1292
}
0 commit comments