1
votes

I am trying to model a social network with Neo4J. This requires a user can have multiple relationships with another user. When I try to persist these relationships, only one is stored. For example, this is the test unit I do:

@Test
public void testFindConnections() {

    Id id1 = new Id();
    id1.setId("first-node");

    Id id2 = new Id();
    id2.setId("second-node");
    idService.save(id2);

    id1.connectedTo(id2, "first-rel");
    id1.connectedTo(id2, "second-rel");

    idService.save(id1);

    for (Id im : idService.findAll()) {
        System.out.println("-" + im.getId());
        if (im.getConnections().size() > 0) {
            for (ConnectionType ite : im.getConnections()) {
                System.out
                        .println("--" + ite.getId() + " " + ite.getType());
            }
        }
    }
}

This should output:

-first-node
--0 first-rel
--1 second-rel
-second-node
--0 first-rel
--1 second-rel

However, it outputs:

-first-node
--0 first-rel
-second-node
--0 first-rel

This is my node entity:

@NodeEntity
public class Id {

    @GraphId
    Long nodeId;
    @Indexed(unique = false)
    String id;

    @Fetch
    @RelatedToVia(direction=Direction.BOTH)
    Collection<ConnectionType> connections = new HashSet<ConnectionType>();
}

And my relationship entity:

@RelationshipEntity(type = "CONNECTED_TO")
public class ConnectionType {

    @GraphId Long id;
    @StartNode Id fromUser;
    @EndNode Id toUser;

    String type;
}

What could the problem be? Is there any other way to model several relationships between nodes?

1

1 Answers

4
votes

This is not a shortcoming of Neo4j, it is a restriction of Spring Data Neo4j.

Usually if you have different types of relationships it would make sense to actually choose different relationship-types too, and not use a relationship-property for this.

CONNECTED_TO is also pretty generic.

Id is also a pretty generic class, shouldn't that be User or something similar?

FRIEND COLLEAGUE etc would be more meaningful.


That said, if you want to stay on your model you can either use

template.createRelationshipBetween(entity1,entity2,type,properties,true)

The true stands for allow-duplicates.

Alternatively use two different target types for the 2 types of relationships and use

@RelatedTo(enforceTargetType=true)