@@ -547,34 +547,43 @@ public boolean containsPossibleCircles(Predicate<PropertyFilter.RelaxedPropertyP
547
547
private boolean calculatePossibleCircles (Predicate <PropertyFilter .RelaxedPropertyPath > includeField ) {
548
548
Collection <RelationshipDescription > relationships = new HashSet <>(getRelationshipsInHierarchy (includeField ));
549
549
550
- Set <RelationshipDescription > processedRelationships = new HashSet <>();
551
550
for (RelationshipDescription relationship : relationships ) {
552
551
PropertyFilter .RelaxedPropertyPath relaxedPropertyPath = PropertyFilter .RelaxedPropertyPath .withRootType (this .getUnderlyingClass ());
553
552
if (!filterProperties (includeField , relationship , relaxedPropertyPath )) {
554
553
continue ;
555
554
}
556
- if (processedRelationships .contains (relationship )) {
555
+ // We don't look at the direction because we need to look for cycles based on the modelled relationship
556
+ // direction instead of the "real graph" directions
557
+ NodeDescription <?> targetNode = relationship .getTarget ();
558
+ if (this .equals (targetNode )) {
557
559
return true ;
558
560
}
559
- processedRelationships .add (relationship );
560
561
String relationshipPropertiesPrefix = relationship .hasRelationshipProperties () ? "." + ((Neo4jPersistentEntity <?>) relationship .getRelationshipPropertiesEntity ())
561
562
.getPersistentProperty (TargetNode .class ).getFieldName () : "" ;
562
- if (calculatePossibleCircles (relationship .getTarget (), processedRelationships , includeField , relaxedPropertyPath .append (relationship .getFieldName () + relationshipPropertiesPrefix ))) {
563
+
564
+ // Branch out with the nodes already visited before
565
+ Set <NodeDescription <?>> visitedNodes = new HashSet <>();
566
+ visitedNodes .add (targetNode );
567
+ if (calculatePossibleCircles (targetNode , visitedNodes , includeField , relaxedPropertyPath .append (relationship .getFieldName () + relationshipPropertiesPrefix ))) {
563
568
return true ;
564
569
}
565
570
}
566
571
return false ;
567
572
}
568
573
569
- private boolean calculatePossibleCircles (NodeDescription <?> nodeDescription , Set <RelationshipDescription > processedRelationships , Predicate <PropertyFilter .RelaxedPropertyPath > includeField , PropertyFilter .RelaxedPropertyPath path ) {
574
+ private boolean calculatePossibleCircles (NodeDescription <?> nodeDescription , Set <NodeDescription <?>> visitedNodes , Predicate <PropertyFilter .RelaxedPropertyPath > includeField , PropertyFilter .RelaxedPropertyPath path ) {
570
575
Collection <RelationshipDescription > relationships = ((DefaultNeo4jPersistentEntity <?>) nodeDescription ).getRelationshipsInHierarchy (includeField , path );
571
576
572
577
for (RelationshipDescription relationship : relationships ) {
573
- if (processedRelationships .contains (relationship )) {
578
+ NodeDescription <?> targetNode = relationship .getTarget ();
579
+ if (visitedNodes .contains (targetNode )) {
574
580
return true ;
575
581
}
576
- processedRelationships .add (relationship );
577
- if (calculatePossibleCircles (relationship .getTarget (), processedRelationships , includeField , path .append (relationship .getFieldName ()))) {
582
+ visitedNodes .add (targetNode );
583
+
584
+ // Branch out again for the sub-tree with all previously visited nodes
585
+ Set <NodeDescription <?>> branchedVisitedNodes = new HashSet <>(visitedNodes );
586
+ if (calculatePossibleCircles (targetNode , branchedVisitedNodes , includeField , path .append (relationship .getFieldName ()))) {
578
587
return true ;
579
588
}
580
589
}
0 commit comments