3

I'm having difficulties retrieving relationships when the relationship type is annotated with a @RelationshipType field.

The relationships look correct in Neoclipse, but I'm retrieving no results in my application.

The code that doesn't work is (simplified):

@NodeEntity
public abstract class Entity {

    @RelatedToVia
    private Collection<Relationship> relationships;

    public Relationship relatedTo(Entity entity, String type) {
        Relationship relationship = new Relationship(type, this, entity);
        relationships.add(relationship);

        return relationship;
    }

    ...
}

and:

@RelationshipEntity
public class Relationship {

    @RelationshipType
    private String type;

    ...
 }

The code that does work is:

@RelationshipEntity(type = "something")
public class Relationship {

   ...
}

However, this doesn't suit my use case (I have a bunch of different Relationship types between arbitrary combinations of Entity instances.

The full test code is below. Agency and Item are both subclasses of Entity.

// Create first entity
Agency arnz = agencyRepository.save(new Agency());
arnz.setCode("ARNZ");
agencyRepository.save(arnz);

// Create second entity
Item r123 = itemRepository.save(new Item());
r123.setCode("R123");

// Create parent/child relationship between entities
r123.relatedTo(arnz, EntityRelationshipType.PARENT);
itemRepository.save(r123);

// Retrieve entity from database
Entity entity = itemRepository.findByCode("R123");

// Verify that relationship is present
assertThat(entity.getRelationships().iterator().hasNext(), is(true));

The final line is where the test is failing. Any clues?

M

PS. I'm a rank amateur with Neo4j and just happened to find @RelationshipType, so I may well be doing something laughably wrong. I hope so!

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
nullPainter
  • 2,676
  • 3
  • 22
  • 42
  • Further experimentation shows that `itemRepository.getRelationshipBetween(r123, arnz, Relationship.class, EntityRelationshipType.PARENT);` returns the relationship as expected. However again, this isn't what my use case demands so isn't of much use! – nullPainter Jun 02 '12 at 22:14
  • Also, following on from the test code above, `Node node = template.getNode(entity.getId());` and an subsequent call to `node.getRelationships();` also correctly returns the relationship, just in a less-useful node4j raw `Relationship` type. So, clearly a Spring Data implementation issue rather than something fundamentally wrong in my graph? – nullPainter Jun 02 '12 at 22:31
  • And it works if I change the annotation on the collection to `@RelatedToVia(direction = Direction.BOTH, type = EntityRelationshipType.PARENT)` (i.e., adding a `type`). Which again isn't very useful as I require a heterogeneous set of relationship types in the same collection. Or is this just a restriction of the framework? I'm using 2.1.0.BUILD-SNAPSHOT. – nullPainter Jun 02 '12 at 22:53
  • Should be in now, can you try if it works for you? – Michael Hunger Aug 08 '12 at 06:33

1 Answers1

2

Sorry to disappoint you, but during the retrieval the code right now doesn't look for the type class but rather for the type from @RelatedToVia or @RelationshipEntity or the field name relationships as relationship-type. But you're making a valid point, can you please raise in issue in JIRA?

Did you look into template.getRelationshipsBetween ?

Why don't you create individual classes for your relationships? What is the use-case for this approach?

Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • Thanks Michael, I did suspect as much. The only reason that I'm not creating individual classes for my relationships is elegance from a Java perspective. I have `Entity`<-- `Relationship` --> `Entity` domain objects, with the `Relationship` containing year metadata. There are around eight bidirectional relationship types possible between each Entity subclass ("Agency is CONTROLLED_BY Series, Series is also CREATED_BY Agency, Series is GOVERNED_BY Series, etc.). Creating eight different `Relationship` objects and eight different maps is a bit awkward if the classes are otherwise identical. – nullPainter Jun 03 '12 at 21:00
  • I did look at `template.getRelationshipsBetween`, which works well. However I'm trying to build a data/graph explorer - user selects an entity from search results, and the explorer displays the entity and its related entities up to two deep. Selecting a related entity centres on that entity, etc. So, the use case doesn't at any point specify explicit knowledge of related entities for querying up-front. I suppose an alternative is to just use a RELATED_TO relationship 'type' and store the specifics in a standard field. – nullPainter Jun 03 '12 at 21:04
  • I should have clarified in my first comment - the `Entity` classes are subclassed to provide additional fields, however the `Relationship` class is the same for all. So, we could have `Agency` <-- `Relationship` --> `Series`, `Agency` <-- `Relationship` --> `Agency`, etc. So, each of the relationship types between entities share a common `Relationship` class as relational metadata. – nullPainter Jun 03 '12 at 21:10
  • 2
    Actually @Michael, the implementation of my use-case was too naive and too heavily influenced by the data structure of an existing legacy system which was backed by a relational database. Storing multiple relationship types in the same bidirectional collection really makes no sense for my traversal use-case, nor my underlying data structure. I might raise a JIRA regardless, in case heterogeneous collections are useful for someone else. – nullPainter Jun 04 '12 at 20:41
  • Thanks a lot. We had some more use-cases where people wanted to store polymorphic data on relationship-entities and use dynamic rel-types for those. So it is now in JIRA and being worked on. – Michael Hunger Jun 13 '12 at 22:27