@@ -547,34 +547,43 @@ public boolean containsPossibleCircles(Predicate<PropertyFilter.RelaxedPropertyP
547547 private boolean calculatePossibleCircles (Predicate <PropertyFilter .RelaxedPropertyPath > includeField ) {
548548 Collection <RelationshipDescription > relationships = new HashSet <>(getRelationshipsInHierarchy (includeField ));
549549
550- Set <RelationshipDescription > processedRelationships = new HashSet <>();
551550 for (RelationshipDescription relationship : relationships ) {
552551 PropertyFilter .RelaxedPropertyPath relaxedPropertyPath = PropertyFilter .RelaxedPropertyPath .withRootType (this .getUnderlyingClass ());
553552 if (!filterProperties (includeField , relationship , relaxedPropertyPath )) {
554553 continue ;
555554 }
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 )) {
557559 return true ;
558560 }
559- processedRelationships .add (relationship );
560561 String relationshipPropertiesPrefix = relationship .hasRelationshipProperties () ? "." + ((Neo4jPersistentEntity <?>) relationship .getRelationshipPropertiesEntity ())
561562 .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 ))) {
563568 return true ;
564569 }
565570 }
566571 return false ;
567572 }
568573
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 ) {
570575 Collection <RelationshipDescription > relationships = ((DefaultNeo4jPersistentEntity <?>) nodeDescription ).getRelationshipsInHierarchy (includeField , path );
571576
572577 for (RelationshipDescription relationship : relationships ) {
573- if (processedRelationships .contains (relationship )) {
578+ NodeDescription <?> targetNode = relationship .getTarget ();
579+ if (visitedNodes .contains (targetNode )) {
574580 return true ;
575581 }
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 ()))) {
578587 return true ;
579588 }
580589 }
0 commit comments