Skip to content

Commit 14b8195

Browse files
committed
GH-2317 - Move logic towards visited nodes instead of relationships.
Closes #2317
1 parent 2fe1366 commit 14b8195

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jPersistentEntity.java

+17-8
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)