diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/MappingSupport.java b/src/main/java/org/springframework/data/neo4j/core/mapping/MappingSupport.java index bed05ae27..6d2ca90ec 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/MappingSupport.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/MappingSupport.java @@ -19,6 +19,7 @@ import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -108,5 +109,22 @@ public final class MappingSupport { Object getRelatedEntity() { return relatedEntity; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RelationshipPropertiesWithEntityHolder that = (RelationshipPropertiesWithEntityHolder) o; + return relationshipProperties.equals(that.relationshipProperties) && relatedEntity.equals(that.relatedEntity); + } + + @Override + public int hashCode() { + return Objects.hash(relationshipProperties, relatedEntity); + } } } diff --git a/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java b/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java index 7fb847aa2..641ccaceb 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java @@ -88,6 +88,7 @@ import org.springframework.data.neo4j.integration.shared.common.AltLikedByPerson import org.springframework.data.neo4j.integration.shared.common.AltPerson; import org.springframework.data.neo4j.integration.shared.common.AnotherThingWithAssignedId; import org.springframework.data.neo4j.integration.shared.common.BidirectionalEnd; +import org.springframework.data.neo4j.integration.shared.common.BidirectionalSameEntity; import org.springframework.data.neo4j.integration.shared.common.BidirectionalStart; import org.springframework.data.neo4j.integration.shared.common.Club; import org.springframework.data.neo4j.integration.shared.common.ClubRelationship; @@ -2124,6 +2125,35 @@ class RepositoryIT { assertThat(records).hasSize(1); } } + + @Test // DATAGRAPH-1469 + void saveBidirectionalSameEntityRelationship(@Autowired BidirectionalSameEntityRepository repository) { + BidirectionalSameEntity entity1 = new BidirectionalSameEntity("e1"); + BidirectionalSameEntity entity2 = new BidirectionalSameEntity("e2"); + + BidirectionalSameEntity.BidirectionalSameRelationship e1KnowsE2 = + new BidirectionalSameEntity.BidirectionalSameRelationship(entity2); + BidirectionalSameEntity.BidirectionalSameRelationship e2KnowsE1 = + new BidirectionalSameEntity.BidirectionalSameRelationship(entity1); + + entity1.setKnows(Collections.singletonList(e1KnowsE2)); + entity2.setKnows(Collections.singletonList(e2KnowsE1)); + + repository.save(entity1); + try (Session session = createSession()) { + List records = session.run( + "MATCH (e:BidirectionalSameEntity{id:'e1'})-[:KNOWS]->(:BidirectionalSameEntity{id:'e2'}) RETURN e") + .list(); + + assertThat(records).hasSize(1); + + records = session.run( + "MATCH (e:BidirectionalSameEntity{id:'e2'})-[:KNOWS]->(:BidirectionalSameEntity{id:'e1'}) RETURN e") + .list(); + + assertThat(records).hasSize(1); + } + } } @Nested @@ -3597,6 +3627,8 @@ class RepositoryIT { interface EntityWithRelationshipPropertiesPathRepository extends Neo4jRepository {} + interface BidirectionalSameEntityRepository extends Neo4jRepository {} + @SpringJUnitConfig(Config.class) static abstract class IntegrationTestBase { diff --git a/src/test/java/org/springframework/data/neo4j/integration/shared/common/BidirectionalSameEntity.java b/src/test/java/org/springframework/data/neo4j/integration/shared/common/BidirectionalSameEntity.java new file mode 100644 index 000000000..485af16ea --- /dev/null +++ b/src/test/java/org/springframework/data/neo4j/integration/shared/common/BidirectionalSameEntity.java @@ -0,0 +1,60 @@ +/* + * Copyright 2011-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.neo4j.integration.shared.common; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; +import org.springframework.data.neo4j.core.schema.Relationship.Direction; +import org.springframework.data.neo4j.core.schema.RelationshipProperties; +import org.springframework.data.neo4j.core.schema.TargetNode; + +import java.util.List; + +/** + * @author Gerrit Meier + */ +@Node +public class BidirectionalSameEntity { + + @Id + private String id; + + @Relationship(type = "KNOWS", direction = Direction.OUTGOING) + private List knows; + + public BidirectionalSameEntity(String id) { + this.id = id; + } + + public void setKnows(List knows) { + this.knows = knows; + } + + /** + * Relationship properties class for the same relationship. + */ + @RelationshipProperties + public static class BidirectionalSameRelationship { + + public BidirectionalSameRelationship(BidirectionalSameEntity entity) { + this.entity = entity; + } + + @TargetNode + BidirectionalSameEntity entity; + } +}