sparkyspider
sparkyspider

Reputation: 13519

Spring Data Neo4j: Complex relationships not persisting

When adding multiple relationships between nodes simultaneously, only some of them are created. In the example below, the calls to makeUser(...) are only populating some of the relationships.

Main

@Transactional
void clearDatabase() {
    session.execute("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r");
}

void createPeople() {

    Person mark = new Person("Mark");
    mark.password = "mark123";
    people.save(mark);

    Organisation noxRentals = new Organisation("Nox Rentals");
    organisations.save(noxRentals);

    makeUser(noxRentals, mark, "Administrator", Right.ADMINISTRATE);
    makeUser(noxRentals, richard, "Administrator", Right.ADMINISTRATE);
    makeUser(classicVillas, mark, "Administrator", Right.ADMINISTRATE);
    makeUser(classicVillas, richard, "Administrator", Right.ADMINISTRATE);
    makeUser(classicVillas, charlotte, "Reservations", Right.LOGIN, Right.SEND_QUOTES);

}

@Transactional
void makeUser (Organisation organisation, Person person, String role, Right...rights) {
    IsUser account = organisation.addUser(person, role);
    account.addRights(rights);
    organisations.save(organisation);
}

void run() {
    clearDatabase();
    createPeople();
}

Resulting in (notice Nox has no relationships):

Missing Relationships

Organisation.java

@NodeEntity
public class Organisation extends NitroBaseEntity {

    @Relationship(type = "IsUser", direction = Relationship.INCOMING)
    Set<IsUser> users = new HashSet<>();

    public IsUser addUser(Person person, String role) {
        IsUser user = new IsUser(person, this, role);
        this.users.add(user);
        return user;
    }
}

Person.java

@NodeEntity
public class Person extends NitroBaseEntity {

    @Property
    String password;

    @Relationship(type = "IsUser", direction = Relationship.OUTGOING)
    Set<IsUser> users = new HashSet<>();

    public Set<IsUser> getUserAccounts() {
        return this.users;
    }

}

IsUser.java

@RelationshipEntity
public class IsUser {

    @GraphId
    Long id;

    @StartNode
    public Person person;

    @EndNode
    public Organisation organisation;

    @Property
    public String role;

    @Property
    public Set<Right> rights = new HashSet<>();

    public IsUser (Person person, Organisation organisation, String role) {
        this.person = person;
        this.organisation = organisation;
        this.role = role;
    }
}

Complete source code: https://bitbucket.org/sparkyspider/neo4j-sandbox-4/src/22eb3aba82e33dfe473ee15e26f9b4701c62fd8e/src/main/java/com/noxgroup/nitro/config/DatabaseInitializer.java?at=master

Upvotes: 0

Views: 186

Answers (1)

Luanne
Luanne

Reputation: 19373

There are two things missing-

  1. The type has to be specified on the @RelationshipEntity as well, like this @RelationshipEntity(type = "IsUser")
  2. In Organisation.addUser(), add the IsUser to the Person too, something like person.users.add(user);. The entities have to be navigable from both ends.

Upvotes: 2

Related Questions