question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When a relationship has been mapped already (scalar), it is re-mapped to an iterable if the object model is not navigable in both directions

See original GitHub issue

The following entities:

@NodeEntity
class MyEntity{
    @GraphId Long graphId;
}

class MyResource extends MyEntity{
    @Relationship(type="HAS_CHILD", direction = Relationship.INCOMING)
    MyContainer parent;
}

class MyContainer extends MyResource{
    @Relationship(type="HAS_CHILD", direction = Relationship.OUTGOING)
    List<MyResource> children = new ArrayList<>();

    MyResource additionalChild;
}

created this graph

MyContainer{
  additionalChild=MyResource{graphId=null, name='anotherChild'} 
  children=[
    MyResource{graphId=null, name='child1'}, 
    MyResource{graphId=null, name='child2'}
  ]
}

loading it back gives:

MyContainer{
  additionalChild=MyResource{graphId=95, name='anotherChild'} 
  children=[
    MyResource{graphId=95, name='anotherChild'}, 
    MyResource{graphId=97, name='child2'}, 
    MyResource{graphId=96, name='child1'}
  ]
}

Somehow additionalChild bleeds over into the children collection.

Full example is on Github: https://github.com/m2spring/ogm-eval/tree/single-child-in-children

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
luannecommented, Nov 23, 2015

@charliebonza there are two reasons your test was failing. The first is that the annotations need to be explicit. INCOMING relationships must have annotations on methods as well if present.

In cases where the mapping may be ambiguous like the one in this issue as well as your test case, recommendation is that a) the objects be navigable in both directions and b) the @Relationship annotations are explicit. This means if you have methods, they must be annotated.

The User should now look like:


    @Relationship(type = "OWNER", direction = Relationship.INCOMING)
    private Set<OwnedLicensedEntity> owned;

    @Relationship(type = "LICENSEE", direction = Relationship.INCOMING)
    private Set<OwnedLicensedEntity> licensed;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Relationship(type = "LICENSEE", direction = Relationship.INCOMING)
    public Set<OwnedLicensedEntity> getLicensed() {
        return licensed;
    }

    @Relationship(type = "LICENSEE", direction = Relationship.INCOMING)
    public void setLicensed(Set<OwnedLicensedEntity> licensed) {
        this.licensed = licensed;
    }

    @Relationship(type = "OWNER", direction = Relationship.INCOMING)
    public Set<OwnedLicensedEntity> getOwned() {
        return owned;
    }

    @Relationship(type = "OWNER", direction = Relationship.INCOMING)
    public void setOwned(Set<OwnedLicensedEntity> owned) {
        this.owned = owned;
    }

and OwnedLicensedEntity like

@Relationship(type = "OWNER", direction = Relationship.OUTGOING)
    private User owner;

    @Relationship(type = "LICENSEE", direction = Relationship.OUTGOING)
    private Set<User> licensees;

    @Relationship(type = "LICENSEE", direction = Relationship.OUTGOING)
    public Set<User> getLicensees() {
        return licensees;
    }

    @Relationship(type = "LICENSEE", direction = Relationship.OUTGOING)
    public void setLicensees(Set<User> licensees) {
        this.licensees = licensees;
    }

    @Relationship(type = "OWNER", direction = Relationship.OUTGOING)
    public User getOwner() {
        return owner;
    }

    @Relationship(type = "OWNER", direction = Relationship.OUTGOING)
    public void setOwner(User owner) {
        this.owner = owner;
    }

The second issue contributing to this behaviour was issue #85 which is now fixed and available in 1.1.4-SNAPSHOT

0reactions
tarehartcommented, Nov 24, 2015

@luanne perfect, thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

21. Iterables and iterators - Exploring JS
Making iteration over properties the default would mean mixing those levels, which would have two disadvantages: You can't iterate over the properties of...
Read more >
Relationships, navigation properties, and foreign keys - EF6
Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the ...
Read more >
Iteration protocols - JavaScript - MDN Web Docs
The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when...
Read more >
What are iterator, iterable, and iteration? - Stack Overflow
Iteration is a general term for taking each item of something, one after another. Any time you use a loop, explicit or implicit, ......
Read more >
JSON-LD 1.1 Processing Algorithms and API - W3C
A map entry in the body of a JSON-LD document whose value is null has the same meaning as if the map entry...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found