0

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?

Emerson Farrugia
  • 11,153
  • 5
  • 43
  • 51
  • I guess this is a dupe of http://stackoverflow.com/questions/15002288/cannot-add-more-than-one-relationship-between-nodes-in-neo4j. In my case, though, it doesn't make sense to have them as separate collections, and circumventing Spring Data to use the template directly is hackish. I guess I'll end up making them nodes instead of relationships. Sigh. – Emerson Farrugia Aug 23 '13 at 13:26

1 Answers1

1

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.

Community
  • 1
  • 1
Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
  • My case isn't a hypergraph. A hyperedge, or n-ary relationship, occurs when a single edge connects more than two vertices. But Contracts aren't edges between more than two nodes, they'r edges between exactly two nodes and should fall smack in the middle of SDN and Neo4j's capabilities. I'll try to use createRelationShipBetween and see if that works. – Emerson Farrugia Aug 23 '13 at 15:28