Emerson Farrugia
Emerson Farrugia

Reputation: 11353

Can a node contain a collection of relationships with the same end node?

I'm using Spring Data Neo4j 2.2.2 and I'm having trouble persisting multiple relationships with the same start and end node.

Assume a Person can have multiple Contracts with a Company. I modelled this as

@NodeEntity
public class Company {...}

and

@NodeEntity
public class Person {

    @RelatedToVia 
    private Set<Contract> contracts;
    ...
}

and

@RelationshipEntity
public class Contract {

    @StartNode
    private Person person;

    @EndNode
    private Company company;
    ...
}

To add a contract to a person, I'm writing code like

Contract contract = new Contract();
contract.setPerson(person);
contract.setCompany(company);
// set other contract properties
person.getContracts().add(contract);
personDao.save(person)

where personDao is a GraphRepository<Person>.

In my tests, I can add a new Contract to a Person if that Person doesn't already have a Contract for the same Company. But if I try to add a new Contract to a Person with the same Company end node as an existing Contract it doesn't get saved.

equals() and hashCode() are implemented against @GraphId, and I've confirmed that all objects are in the Contract Set when I call save. I've also tried with Collection instead of Set to no avail.

Any idea what could be wrong?

Upvotes: 0

Views: 729

Answers (1)

Aravind Yarram
Aravind Yarram

Reputation: 80176

The suggested way to create the 2nd relationship is as below

From reference manual

Note Spring Data Neo4j ensures by default that there is only one relationship of a given type between any two given entities. This can be circumvented by using the createRelationshipBetween() method with the allowDuplicates parameter on repositories or entities.

Contract createContractRelation(Company c, Person p)
{
    //last argument "true" indicates that a duplicate relationship should be created
    Contract contract = template.createRelationshipBetween(c, p, Contract.class, "Contract", true);

    contract.setPerson(person);
    contract.setCompany(company);

    template.save(contract);

    return contract;
}

I was however able to create a maximum of only 2 relationships with this. More than two isn't working. I've an open question regarding this here: unable to create more than 2 same relations between two nodes

Another approach

I realized what you (and I) have is a Hypergraph situation. Neo4j only supports property graphs but there is a way to represent this using Neo4j as suggested in this cookbook.

Upvotes: 1

Related Questions